HTML Multi-Themes Formatter
Options and examples for Lumis multi-theme HTML output using CSS custom properties.
One HTML block that supports multiple themes via CSS custom properties. Useful for light/dark mode.
Options
| Runtime | Options |
|---|---|
| Rust | language, themes, default_theme, css_variable_prefix, pre_class, pre_attrs, code_attrs, italic, include_highlights, rainbow_brackets, highlight_lines, line_numbers, header |
| Elixir | language, themes, default_theme, css_variable_prefix, pre_class, pre_attrs, code_attrs, italic, include_highlights, rainbow_brackets, highlight_lines, line_numbers, header |
| JavaScript | language, themes, defaultTheme, cssVariablePrefix, preClass, preAttrs, codeAttrs, italic, includeHighlights, rainbowBrackets, highlightLines, lineNumbers, header |
| Java | Not currently supported in lumis4j |
| CLI | --themes, --default-theme, --css-variable-prefix, --pre-class, --pre-attr, --no-pre-attr, --code-attr, --no-code-attr, --italic, --include-highlights, --rainbow-brackets, --highlight-lines, --highlight-lines-class, --highlight-lines-style, --line-numbers, --header-open, --header-close |
Basic example
import {highlight} from '@lumis-sh/lumis'
import {htmlMultiThemes} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import latte from '@lumis-sh/themes/catppuccin_latte'
import frappe from '@lumis-sh/themes/catppuccin_frappe'
const html = await highlight(
'const x = 1',
htmlMultiThemes({
language: javascript,
themes: {light: latte, dark: frappe},
defaultTheme: 'light-dark()',
})
)
cssVariablePrefix
By default, CSS variables are prefixed with --lumis (e.g., --lumis-light, --lumis-dark-bg). Override the prefix if it conflicts with your CSS. Produces variables like --code-light, --code-dark-bg, etc.
const html = await highlight(
'const x = 1',
htmlMultiThemes({
language: javascript,
themes: {light: latte, dark: frappe},
cssVariablePrefix: '--code',
})
)
defaultTheme
Controls what color values appear inline (not just as CSS variables):
| Value | Behavior |
|---|---|
omitted / null | CSS variables only, no inline colors |
"light" | Inline colors from the light theme, CSS variables for all themes |
"light-dark()" | Uses CSS light-dark() function for automatic OS-level switching |
What light-dark() covers
CSS light-dark() is a color function, so only color and background-color use it. For font-weight, font-style and text-decoration, a value both themes share is written as an ordinary declaration; a value they disagree on is written as --lumis-light-* and --lumis-dark-* variables with no declaration, since only a rule of your own can switch it. Leaving it out of the style attribute is what keeps that rule from needing !important, see Light/Dark Mode.
Output format
HTML Multi-Themes keeps the same HTML structure, but each token carries CSS variables for one or more themes:
<pre class="lumis" style="--lumis-light-bg:#eff1f5; --lumis-dark-bg:#303446;">
<code class="language-javascript" translate="no" tabindex="0">
<div class="l-line" data-line="1">
<span style="--lumis-dark:#ca9ee6; --lumis-light:#8839ef;">const</span>
</div>
</code>
</pre>
<pre class="lumis">carries shared background and theme variables<code class="language-*">identifies the language and keeps the block focusable<div class="l-line" data-line="N">wraps each line<span class="l-line-number">opens the line whenline_numbersis on, see Line Numbers- A source
\nor\r\nsits just before that line's</div>; an unterminated final line gets no added newline <span style="--lumis-...">carries per-theme token colors and font styles
Good uses
- light/dark mode
- user-selectable theme switching
- one HTML block shared across themes