WebCraft

light-dark()

One declaration that covers both themes

follows the themeok
color-scheme: normalstuck

Caveatlight-dark() does not look at the media query, it looks at the computed color-scheme of the element. Leave that unset and it silently returns the first value forever — the second swatch above is the same CSS with color-scheme: normal, and it never changes. A theme that half works is harder to find than one that does not work at all, and this is the usual reason for it.

FallbackAn engine without the function drops the whole declaration, so the property keeps whatever value came before it in the cascade. Declare the plain colour first and light-dark() after: old engines keep the first, new ones take the second, and no feature query is needed.

CSS
.panel {
  /* without this, always the light one */
  color-scheme: light dark;

  /* old engines stop here */
  background: #f6f4ec;
  background: light-dark(#f6f4ec, #171d28);
}

Published

Questions

<details name>

Why does light-dark() always return the light colour?

The element's computed color-scheme is still normal, and in that state the function picks the first value. Set color-scheme: light dark on :root; it inherits, so every light-dark() below it starts following the system theme.

Does light-dark() work with a manual theme toggle?

Yes, because it reads color-scheme and ignores the media query. Have the toggle set color-scheme: light or color-scheme: dark on the root element and every light-dark() value switches with it, whatever the operating system prefers.

What happens to light-dark() in browsers that do not support it?

The whole declaration is dropped as invalid and the property keeps its previous value. Write the plain light colour on the line before, so older engines keep that one and newer ones override it with light-dark().