← All writing
Craft · · 2 min

light-dark()

It removes the duplicate token block, and the one thing it needs to work is the declaration everybody forgets.

CSS Small Print

The usual shape of a theme is a block of custom properties and then a second block overriding every one of them.

tokens.css
:root {
  color-scheme: light dark;
CSS
tokens.css
  --paper: light-dark(#fdfcfb, #12241c);
  --ink:   light-dark(#1b1d1b, #f4f1ee);
}
CSS

light-dark() takes the first value in light and the second in dark, and the two live on the same line, which is the actual benefit: a token and its counterpart cannot drift apart when they are eight characters from each other.

The declaration that makes it work is color-scheme. Without it the function resolves to its light value and nothing else happens. There is no warning anywhere. That is the whole of the debugging story for this. So I will say it twice: if light-dark() appears to be ignoring dark mode, you have not set color-scheme.

color-scheme is separately worth setting anyway, because it is what tells the browser to render form controls, scrollbars and the canvas in the dark variants. A site that themes everything itself and forgets this ends up with dark cards and a bright white select.

It does not help on a site with an explicit theme toggle rather than a purely automatic one, because a toggle needs a data-theme on the root to override the OS, and at that point you are back to two blocks. This site is that case, which is a slightly funny position to be recommending the other approach from.

Read similar posts
2 min

scrollbar-gutter

The layout shifts by fifteen pixels when a modal opens, everybody blames the modal, and the actual cause is the scrollbar disappearing along with it.

2 min

text-wrap: balance and pretty

Two values that fix the two ugliest things typesetting does on the web, and the rule for which to use is entirely about how many lines you have.