Styles for the HTML output are set with CSS variables that override defaults set by a theme object. You can set your own styles by either defining your own theme object or overriding the default theme's styles with CSS variables. The latter approach is much more powerful and flexible. CSS should be used in place of the theme object whenever possible.
The most direct and most scalable way to tune your animation's look and feel is to overwrite any or all of the 140+ available CSS variables. This enables you to tweak colors, animation speeds and basically everything else.
The following animation uses a different theme from all other animations in this documentation. Most of the differences come down to changes to CSS variables.
// No types :( function add(a, b) { return a + b; }
// Yes types! function add( a: number, b: number ): number { return a + b; }
// Yes types with generics! function add<T extends number | bigint>( a: T, b: T ): T { return a + b; }
See the CSS variable reference for a full list of things to tweak and check out the guide to dark and light modes for information on conditional styling specifically.
Theme objects are JavaScript/JSON objects that define the style defaults for the output, which are in turn overwritten by CSS variables. Theme objects are unwieldy monsters and less powerful than CSS variables. Currently, their precise format also has a habit of changing in incompatible ways, so you should try to stick to CSS if at all possible.
The built-in theme objects are available as exports from the main package, together with a Zod schema to validate theme objects with. TypeScript users can also import and use the Theme
type.
import { defaultTheme, themeSchema, type Theme } from "@codemovie/code-movie";
let validatedTheme: Theme = themeSchema.parse(defaultTheme);
// Throws errors if the theme does not conform to the expected type
1234import { defaultTheme, themeSchema, type Theme } from "@codemovie/code-movie";
let validatedTheme: Theme = themeSchema.parse(defaultTheme);
// Throws errors if the theme does not conform to the expected type
Check out the guide to dark and light modes for information on conditional styling specifically.
CSS variables and theme objects allow you to customize syntax highlighting, decoration styles and a few other basics, like the scene's background color. If you want to go beyond that and eg. render your animation into something like an editor UI, you can additional HTML and CSS APIs ("styling hooks").
The HTML output of every animation contains 10 <div>
elements named cm-box0
, cm-box1
... cm-box9
that exist only as hooks for style customization. You (or your friendly CSS wizard neighbor) can use each box to draw a new element, such as a editor window with borders and drop shadows, and decorative elements for the editor window (like title and status bars, or a different background and/or border for the gutter). This actually gives you 32 boxes to play with, because you get to use the divs themselves, their ::before
and ::after
pseudo elements and ::before
and ::after
on the animation element itself.
Since all animations consist of absolutely positioned HTML elements, you can also use absolute positioning to render elements below or above the actual code. As children of the animation element, HTML hooks inherit all of the animation's important CSS properties (such as the transition-duration
), including CSS hooks containing important meta information.
Every animation hosts some pre-computed CSS variables, such as the number of rows, the total width, or the width of the line number column. These variables are not meant to be changed, but rather to be read by your CSS. Information like the height of the entire animation or the width of the line number column is useful if you want to add dimension-dependent borders, backgrounds, or decorative gimmicks to your animation, probably using the HTML hooks mentioned above.
See the styling hook reference for a full list of variables to hook into.
There are a few typography-related edge cases to consider when you venture too far past monospaced ASCII. If you don't intend to do that, you can ignore this section.
Code.Movie works on the assumption that you use a monospaced font for code. It creates a grid based on the width of the 0
character in your main font (set via font-family
on the container element) and places every character and decoration on this grid. Anything but fixed-width fonts will lead to terrible-looking results.
CJK full-width characters such as 한 occupy two grid columns.
The first thing to note about emoji is that whether or not a character is rendered as an emoji (and how it gets rendered) depends entirely on the font being used.
Emoji, like CJK full-width characters, are allocated precisely two columns of space. Whether this will look good depends on the combination of fonts being used. You can use the size-adjust
CSS property in your @font-face
rule to scale emoji to work well with your main font:
@font-face {
font-family: "Noto Color Emoji";
src: url("fonts/NotoColorEmoji-Regular.ttf");
size-adjust: 80%; /* Works well together with Ubuntu Mono */
}
12345@font-face {
font-family: "Noto Color Emoji";
src: url("fonts/NotoColorEmoji-Regular.ttf");
size-adjust: 80%; /* Works well together with Ubuntu Mono */
}