You Can Give A Website Dark Mode With Just One CSS Property

Published:

I’m too lazy to do all the work required to make a proper dark mode for now so I’m trying to find a quick fix. I tried to use filter: invert(100%) on the body but it would literally invert everything, including images and emojis. I was about to give up on it before I came across Jim Nielsen’s post on the color-scheme property which tells the browser what color schemes a site (or element) supports and changes the default color based on the user’s preferences. To use it, you just need to specify the color-scheme property on the :root element.

:root {
    color-scheme: light dark;
}

This supports both light and dark mode. You can also just set light or dark as well as apply the color-scheme property to a specific element. In some environments (like email), you can also apply a <meta name="color-scheme"> tag.

Note that it doesn’t work in Firefox yet.

Issues

When I tried this the link colors didn’t change in Safari resulting in this ugly and inaccessible style. IT worked perfectly fine in Chromium browsers however.

The site’s header with the logo and navigation links in full blue against a black background

Jim had the same issue. Because of that, I ended up implementing some sort of dark mode using Apple’s dynamic system colors. The CSS Colors Module 4 has system colors corresponding to the OS’s UI but they don’t have good support so I just copy-pasted the RGB values. Temper Temper explains how to “fix” dark mode on Safari better than I have. This code should be good enough for you though:

<style>
    :root {
        color-scheme: light dark;
    }

    /* Dark mode correction for WebKit (https://bugs.webkit.org/show_bug.cgi?id=209851)*/
    @media (prefers-color-scheme: dark) {
        a {
            color: rgb(64, 156, 255);
        }
        
        a:visited {
            color: rgb(125, 122, 255);
        }

        a:active {
            color: rgb(255, 100, 130);
        }
    }
</style>

Also, looking at color scheme’s spec, there was this scary warning noting that they don’t guarantee a color palette.

The light and dark color schemes don’t represent an exact color palette (such as black-and-white), but a range of possible palettes. To guarantee specific colors, authors must specify those colors themselves. Note also that, consequently, pairing default or <system-color> colors with author-specified colors cannot guarantee any particular contrast level; it might be necessary to set both foreground and background colors together to ensure legibility.

Given those issues my attempt to implement dark mode lazily has become the start of an interesting journey. Still, it’s worth putting in.

Additional Reading