Light/Dark Mode
The multi-themes formatter renders one HTML block with CSS variables for each theme. You control which theme is active with CSS. There are three approaches, from simplest to most flexible.
1. CSS light-dark() function
The simplest option. The browser switches automatically based on the OS theme. Requires color-scheme: light dark on the root element.
Required CSS for the rendered HTML output:
html {
color-scheme: light dark;
}
That's it for runtimes that support HTML Multi-Themes output. No JavaScript or media queries are needed. lumis4j does not support this formatter, and the CLI only generates the HTML; your app or page still needs to provide the CSS.
- JavaScript
- Rust
- Elixir
- Java
- CLI
import {highlight} from '@lumis-sh/lumis'
import {htmlMultiThemes} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import githubLight from '@lumis-sh/themes/github_light'
import githubDark from '@lumis-sh/themes/github_dark'
const html = await highlight(
'const x = 1',
htmlMultiThemes({
language: javascript,
themes: {light: githubLight, dark: githubDark},
defaultTheme: 'light-dark()',
})
)
use lumis::{highlight, HtmlMultiThemesBuilder, languages::Language, themes};
use std::collections::HashMap;
let mut theme_map = HashMap::new();
theme_map.insert("light".to_string(), themes::get("github_light").unwrap());
theme_map.insert("dark".to_string(), themes::get("github_dark").unwrap());
let html = highlight(
"const x = 1",
HtmlMultiThemesBuilder::new()
.language(Language::Javascript)
.themes(theme_map)
.default_theme("light-dark()")
.build()
.unwrap(),
);
Lumis.highlight!(
"const x = 1",
formatter: {:html_multi_themes,
language: "javascript",
themes: [light: "github_light", dark: "github_dark"],
default_theme: "light-dark()"
}
)
HTML Multi-Themes is not currently supported in lumis4j.
lumis highlight index.js \
--formatter html-multi-themes \
--themes light:github_light \
--themes dark:github_dark \
--default-theme "light-dark()"
2. @media (prefers-color-scheme) with CSS variables
Use this when you need more control than light-dark() provides, or when targeting browsers that don't support it yet. The inline styles render the light theme by default, and a media query overrides with dark theme variables.
Required CSS for the rendered HTML output:
@media (prefers-color-scheme: dark) {
.lumis,
.lumis span {
color: var(--lumis-dark) !important;
background-color: var(--lumis-dark-bg) !important;
font-style: var(--lumis-dark-font-style) !important;
font-weight: var(--lumis-dark-font-weight) !important;
text-decoration: var(--lumis-dark-text-decoration) !important;
}
}
For runtimes that support HTML Multi-Themes, default_theme: "light" makes the light theme's colors render as inline styles. The media query then swaps to the dark theme's CSS variables when the OS is in dark mode. lumis4j does not support this formatter, and the CLI only generates the HTML.
- JavaScript
- Rust
- Elixir
- Java
- CLI
import {highlight} from '@lumis-sh/lumis'
import {htmlMultiThemes} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import githubLight from '@lumis-sh/themes/github_light'
import githubDark from '@lumis-sh/themes/github_dark'
const html = await highlight(
code,
htmlMultiThemes({
language: javascript,
themes: {light: githubLight, dark: githubDark},
defaultTheme: 'light',
})
)
use lumis::{highlight, HtmlMultiThemesBuilder, languages::Language, themes};
use std::collections::HashMap;
let mut theme_map = HashMap::new();
theme_map.insert("light".to_string(), themes::get("github_light").unwrap());
theme_map.insert("dark".to_string(), themes::get("github_dark").unwrap());
let html = highlight(
code,
HtmlMultiThemesBuilder::new()
.language(Language::Javascript)
.themes(theme_map)
.default_theme("light")
.build()
.unwrap(),
);
Lumis.highlight!(
code,
formatter: {:html_multi_themes,
language: "elixir",
themes: [light: "github_light", dark: "github_dark"],
default_theme: "light"
}
)
HTML Multi-Themes is not currently supported in lumis4j.
lumis highlight index.js \
--formatter html-multi-themes \
--themes light:github_light \
--themes dark:github_dark \
--default-theme light
3. Manual switching with JavaScript
Use this when you want a toggle button or user preference that's independent of the OS setting. Add a class to the root element and target it in CSS.
Required CSS for the rendered HTML output:
html.dark .lumis,
html.dark .lumis span {
color: var(--lumis-dark) !important;
background-color: var(--lumis-dark-bg) !important;
font-style: var(--lumis-dark-font-style) !important;
font-weight: var(--lumis-dark-font-weight) !important;
text-decoration: var(--lumis-dark-text-decoration) !important;
}
Toggle JavaScript:
function setTheme(theme) {
if (theme === 'dark') {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}
This pattern works anywhere you render the generated HTML. In Phoenix LiveView, you'd wire the button to a phx-click event that toggles a class via a JS command. lumis4j does not support HTML Multi-Themes, and the CLI only generates the HTML for another renderer to display.
- JavaScript
- Rust
- Elixir
- Java
- CLI
import {highlight} from '@lumis-sh/lumis'
import {htmlMultiThemes} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import githubLight from '@lumis-sh/themes/github_light'
import githubDark from '@lumis-sh/themes/github_dark'
const html = await highlight(
code,
htmlMultiThemes({
language: javascript,
themes: {light: githubLight, dark: githubDark},
defaultTheme: 'light',
})
)
use lumis::{highlight, HtmlMultiThemesBuilder, languages::Language, themes};
use std::collections::HashMap;
let mut theme_map = HashMap::new();
theme_map.insert("light".to_string(), themes::get("github_light").unwrap());
theme_map.insert("dark".to_string(), themes::get("github_dark").unwrap());
let html = highlight(
code,
HtmlMultiThemesBuilder::new()
.language(Language::Javascript)
.themes(theme_map)
.default_theme("light")
.build()
.unwrap(),
);
Lumis.highlight!(
code,
formatter: {:html_multi_themes,
language: "elixir",
themes: [light: "github_light", dark: "github_dark"],
default_theme: "light"
}
)
HTML Multi-Themes is not currently supported in lumis4j.
lumis highlight index.js \
--formatter html-multi-themes \
--themes light:github_light \
--themes dark:github_dark \
--default-theme light
Which approach to use
| Approach | When to use |
|---|---|
light-dark() | Simplest. OS-driven. No extra CSS or JS needed. |
@media prefers-color-scheme | OS-driven but you need the CSS override pattern (wider browser support). |
| Manual switching | User-controlled toggle independent of OS setting. |