Entry 04

One set of color tokens for light and dark

Use it on any site with a dark mode. Each token holds both values, so there is no second block of variables under a media query or a .dark class.

Open
Switch the theme. The page and its controls flip, and the two fixed sections never change.
Code CSS · 8 lines
:root {
  color-scheme: light dark;
  --background: light-dark(oklch(1 0 none), oklch(0.145 0 none));
  --foreground: light-dark(oklch(0.145 0 none), oklch(0.985 0 none));
}

[data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }
Why it works, the rules and the credits 3 reasons · 4 rules · support · credits

Why it works

  1. color-scheme: light dark says the page supports both and follows the system setting. It also switches the browser's own UI, such as form controls, scrollbars and the default page background.
  2. light-dark(a, b) returns a in a light scheme and b in a dark one.
  3. It resolves per element. Set color-scheme on any subtree and every token used inside it flips. The same tokens serve a manual toggle and a section that is always dark.

Rules

  1. Switch themes by setting color-scheme. Never redefine the tokens.
  2. The grays use none for the hue, so they can be mixed with a color later without drifting toward red. OKLCH color has the measurement.
  3. light-dark() takes two colors. Anything else that differs by theme, such as an image, needs its own rule.
  4. Add <meta name="color-scheme" content="light dark"> so the browser paints the right background before the CSS loads.

Support

Chrome
123
Firefox
120
Safari
17.5

Baseline since May 2024.

Credits

Borrowed from: IP, @ipwanciu on X, 2025-10-30

Docs: MDN: light-dark() · MDN: color-scheme · Bramus Van Damme, CSS color-scheme-dependent colors with light-dark()