Skip to main content

HTML-only Dark Mode

First posted in Accessibility, CSS and HTML; updated 3rd June 2021

Progressive enhancement is the most resilient way to design and build for the web. Lots of things can go wrong:

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.


If you enjoyed reading this and want a monthly roundup of my articles delivered to your inbox, just enter your email below.

I don’t collect any data on when, where or if people open the emails I send them. Your email will only be used to send you newsletters and will never be passed on. You can unsubscribe at any time.

More posts

Here are a couple more posts for you to enjoy. If that’s not enough, have a look at the full list.

  1. How I approach CSS: my ABC system

    CSS is easy to write but can become messy and bloated over time. A solid methodology can make maintenance much more comfortable; here’s how I do it.

  2. Critical CSS: what it is, why it’s useful, and how it works

    With Critical CSS, we can give our visitors the most important styling as early as possible and the rest when it’s ready. Here’s why and how to do it.