Dark mode colors without duplicating values
You defined every variable in :root and again inside @media (prefers-color-scheme: dark). light-dark() holds both values in one place so you do not repeat yourself.
2 color-scheme: light dark;
3 color: light-dark(#111, #eee);
4}
5/* One place per property */
2 --text: #111;
3 --bg: #fff;
4}
5
6@media (prefers-color-scheme: dark) {
7:root {
8 --text: #eee;
9 --bg: #222;
10}
11}
12/* Every variable declared twice */
Browser Support for light-dark()
Since 2024 this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
No duplication
First argument is light, second is dark. One declaration, no @media block for each variable.
Works with variables
light-dark(var(--text-light), var(--text-dark)) fits right into a design token setup.
Any property
Use it for color, background, border-color, fill, stroke. Anything that takes a color.
How it works
The old approach was to set your colors (or CSS variables) in :root, then open a @media (prefers-color-scheme: dark) block and redeclare every variable or property for dark mode. That meant every color in two places and easy drift between light and dark.
The modern approach is light-dark(lightValue, darkValue). The browser picks the first value in light mode and the second in dark mode, based on prefers-color-scheme. Pair it with color-scheme: light dark so form controls and scrollbars follow. You can use raw colors or variables: light-dark(var(--text), var(--text-dark)).