I'm rewriting my personal website at the moment to make it easier to update and add things to. In the process I'm trying to keep things as simple as possible.
When I started designing it, I decided to keep the colour scheme completely black and white, with a few splashes of colour. What I realised was that some might prefer a darker colour scheme as opposed to the brilliant white pages I was developing.
But in my mission for simplicity I was determined to use the simplest implementation to achieve my dark theme.
It just so happens that the W3C is drafting up a new standard for a CSS media query that indicates whether the user has requested a light or dark colour theme for the current website. A few browsers support this today including Chrome, Firefox and Safari. See MDN for the details.
By offloading the responsibility of theme preference to the browser, a dark theme implementation can be as simple as a few lines of CSS:
#root {
background: white;
}
@media (prefers-color-scheme: dark) {
#root, img, .no-invert {
filter: invert(100%);
}
}
The way this works is fairly straight-forward:
- When the OS or browser "dark mode" is activated, the CSS in the media tag is applied.
- The
#root
element is inverted from a white background with black text to black with white text (the background colour is required for this to work). - Elements within the root element are inverted again to appear as they normally do.
As expected, elements inverted twice are displayed correctly - see the pills in the top-right:
And for some interesting modifications, other filters could be used in conjunction with invert()
such as contrast()
:
Oh and if you hadn't already guessed, there's also a draft for prefers-contrast
in the works - find the draft here - so that the user can avoid a low contrast theme altogether with a bit of CSS!
Fin
Thanks for reading! Follow me for more posts like this 🚀
Top comments (2)
This works well enough for text, but as soon as you add images it will look weird. I advocate for icons to be inverted, but propose a different grayscaling-based approach for photographic images. But I get it, it's a micro theme, so definitely workable for some use cases.
I really like the idea of subtly altering images to match the surrounding light/dark of the page! Neat!