Easy to implement light and dark themes with light-dark() css function

With dread in my heart, I connected to the world wide web. I wanted to learn how to code the switch between light and dark themes for this blog, expecting some messy javascript hacks to load either one css file or another. To my pleasant surprise, I found a relatively new function that solves this exact problem: light-dark(). It essentially accepts two arguments: a color for the light theme and a color for the dark theme. Since the browser knows what the user wants, it picks the suitable color. That's it!

Dark and light themes

An example from the docs:

:root {
  color-scheme: light dark;
}

body {
  color: light-dark(black, white);
  background-color: light-dark(white, black);
}

Neat, isn't it? Given that I'd already used css variables for all colors, I simply needed to update them to change how text, links, buttons, and other elements would look with both color schemes:

:root {
    color-scheme: light dark;
}

:root {
    --color-bg: light-dark(#fff, #000);
    --color-primary: light-dark(#fc88e5, #f6ade7);
    --color-primary-hover: light-dark(#5dc1a3, #73f7cf);
    --color-primary-muted: #a26897;
    --color-text: light-dark(#121212, #fafafa);
    --color-text-muted: #a5a5a5;
    --color-code-inline: #f6ade7;
    --color-mobile-li-hover: #332e27;
}

However, this function only works for colors. So, for the background image, I used good old media queries:

body {
    font-family: 'Newsreader', sans-serif;
    font-size: 1.25rem;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    background-color: var(--color-bg);
    background-image: url("data:image/svg+xml,%3Csvg width='52' height='26' viewBox='0 0 52 26' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23def0eb' fill-opacity='0.4'%3E%3Cpath d='M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
    color: var(--color-text);
    margin: 0;
}


@media (prefers-color-scheme: dark) {
    body {
        background-image: url('/images/retro/background-dark.gif');
    }
}

It couldn't be easier. According to caniuse.com, this function is has an 86.9% usage rate, so it's safe to utilize unless you need to support older browsers.

Useful links