Home / Snippets / Color & Theming /
light-dark() function
One function, two colors — the browser picks based on color-scheme.
Quick implementation
/* Required: opt in to both schemes */
:root { color-scheme: light dark; }
/* Use light-dark() anywhere you'd put a color */
body {
background: light-dark(
oklch(0.98 0.01 260),
oklch(0.16 0.02 260)
);
color: light-dark(
oklch(0.25 0.02 260),
oklch(0.9 0.01 260)
);
}
.card {
background: light-dark(white, oklch(0.22 0.02 260));
border-color: light-dark(
oklch(0.9 0.02 260),
oklch(0.3 0.02 260)
);
}
Prompt this to your LLM
Includes role, constraints, and design token approach.
You are a senior frontend engineer building a dark-mode color system.
Goal: Use the CSS light-dark() function for automatic dark mode — no JavaScript, no class toggling.
Technical constraints:
- Set color-scheme: light dark on :root (required for light-dark() to work).
- Define all colors as custom properties using light-dark():
--bg, --text, --muted, --accent, --card, --card-border.
- Use oklch() for all color values.
- light-dark(LIGHT_VALUE, DARK_VALUE) — browser picks based on user preference.
- No @media (prefers-color-scheme) queries needed.
- Works with form controls, scrollbars, and system UI automatically via color-scheme.
Return :root block with all custom properties + body/card usage examples.
Why this matters
Before light-dark(), dark mode meant duplicating every color inside a @media (prefers-color-scheme: dark) block. The light-dark() function collapses this into a single declaration — one property, two values. Combined with color-scheme: light dark, the browser also adapts form controls, scrollbars, and system UI automatically.
The logic
color-scheme: light dark on :root tells the browser the page supports both modes. light-dark(A, B) evaluates to A when the used color scheme is light, and B when it's dark. The "used color scheme" comes from the user's OS preference combined with any color-scheme property on the element's ancestors.
Accessibility & performance
Respecting prefers-color-scheme is a WCAG best practice — users who need dark mode for visual comfort get it automatically. light-dark() has zero runtime cost: it's resolved at style computation time, just like any other color function. Supported in Chrome 123+, Safari 17.5+, Firefox 120+.