CSS light-dark() Color Generator
A native CSS function for defining light and dark theme colors in one declaration, no duplicated variable blocks required.
What the light-dark() function does
The CSS light-dark() function accepts two color values — one for light mode, one for dark mode — and returns whichever one is active, based on the page's color-scheme property. It's defined in the CSS Color Module Level 5 specification. Where the older approach required duplicating an entire block of custom properties inside a prefers-color-scheme media query, light-dark() lets you declare both values for a token in a single line:
The color-scheme: light dark; declaration is required — it tells the browser this page supports both themes, which is what light-dark() checks against.
Browser support
light-dark() is supported in all current evergreen browsers (Chrome, Edge, Firefox, and Safari have all shipped support since May 2024) and is on track to reach Baseline "Widely Available" status — the web platform's highest confidence tier — on November 13, 2026. As with any relatively recent CSS feature, check caniuse.com's current data before relying on it without a fallback if you need to support meaningfully older browser versions.
light-dark() vs. the older prefers-color-scheme pattern
| Old pattern | With light-dark() |
|---|---|
:root { --bg: white; }
@media (prefers-color-scheme: dark) {
:root { --bg: black; }
} | :root {
color-scheme: light dark;
--bg: light-dark(white, black);
} |
The old pattern duplicates the whole custom-property block per theme. With more than a handful of tokens, that duplication adds up and drifts out of sync easily. light-dark() keeps each token's two values next to each other in one place.
Try it: build your own token set
Pick a light value and a dark value for each token, then toggle the preview below to see the effect. Already have a light theme in CSS? Paste it below to auto-extract your tokens instead of typing them one at a time.
Currently showing: light
Related
Building out token pairs is only half the decision — read how to actually choose your dark-theme colors, not just switch to them for the framework behind picking good values for each side of a pair, not just the CSS to declare them. And if you're naming more than a handful of tokens, Design Tokens Explained: Primitives vs. Semantic Color Tokens covers the naming structure that keeps a growing token set organized.
Frequently Asked Questions
Do I still need prefers-color-scheme?
Not for the color values themselves — color-scheme: light dark; handles following the OS-level preference automatically. You'd still use a small script for a manual override toggle (letting a visitor pick a theme regardless of their OS setting), which is exactly the pattern this site's own dark-mode toggle uses.
Does light-dark() work with gradients or images?
Yes — per the CSS Color Module Level 5 specification, light-dark() accepts image and gradient values in addition to plain colors, so you can swap an entire background image or gradient between themes the same way.
What browsers support light-dark()?
All current evergreen browsers (Chrome, Edge, Firefox, Safari) support it. Check caniuse.com's current data if you need to support older browser versions specifically.
How is this different from a JS-based dark mode toggle?
light-dark() handles the actual color-switching natively in CSS, with no JavaScript required for that part. A small script is still useful for letting a visitor manually override the OS-level theme, which is a separate concern from how the colors themselves are defined.