HTML-only Dark Mode
Progressive enhancement is the most resilient way to design and build for the web. Lots of things can go wrong:
- Older browsers may not support features like
- Cutting edge features like
focus-visiblemight not be understood by the user’s browser
- The user’s system settings might disallow things like animation
We need a solid starting point before all of these things are added as an enhancement, but let’s take a look at that final bullet: what if the user receives our HTML but no CSS?
CSS is a progressive enhancement, but our stylesheets can contain instructions that make for a more accessible experience; things like the
prefers-color-scheme media query for Dark Mode.
With Dark Mode, we’re respecting our users’ system preferences; their eyes have settle into a that dark UI with light text and as they browse the web, the last thing they want is to be confronted with an obnoxious bright white page.
So what happens when the CSS file containing all the Dark Mode styling fails to load?
You could add Dark Mode styles to a
<style> block in the head of each document, but:
- there can be a lot of Dark Mode rules
- that would delay the rendering of the rest of the page
- our users wouldn’t benefit from caching, so it would slow every page down slightly
- those rules would be heavier (in terms of their specificity) compared to those defined by the user agent
You could add a handful of rules in that
<style> element to cater for the most basic of dark themes, then override or add to them in the CSS file. But that’s more work, as well as being a probable maintenance problem when the developer forgets they’re there.
If only there were some way to tell the browser to use a dark version without CSS…
Imagine my excitement when I found there’s a way to do it in your document’s
<head> with HTML!
<meta name="color-scheme" content="dark light">
Browser support is currently limited to Safari and Chromium-based browsers (Chrome, Opera, Edge, etc.), but that’s currently 84% coverage, so it’s definitely worth adding!
Just one issue before you go ahead: there’s a bug in Safari that makes links less accessible, but thankfully there’s a work-around to fix it.