Dark Mode CSS

I’ve been using dark mode for a lot of my devices for a bit now, I’m a late convert but after developing repeated headaches using my computer all day at work and home (with breaks to look at my bright phone screen) I made the switch and it helped a lot. I solved the problems later with some other technical measures, but kept the dark mode as a backup and general ease-on-the-eyes.

While for years I’d seen buttons on websites that allowed me to turn on some form of “dark mode”, I noticed after enabling it in my system settings (on Windows, macOS, Android), that while many sites remained dark-on-light (light mode) unless their “dark mode” widget was clicked, some automatically picked up on my system settings and adjusted the screen to match.

A bit more hunting discovered the culprit, a CSS media feature called prefers-color-scheme that detects whether a user has requested a dark or light colour theme.

It’s dead simple to use too, much like screen width media queries, you can simply do the following:

p {
  color: #333333;
  background-color: #FAFAF8;
  font-family: Helvetica, Arial, sans-serif;
  font-weight: 300;

@media (prefers-color-scheme: dark) {
  p {
    color: #FAFAF8;
    background-color: #333333;

Now when someone has dark mode enabled, everything will render the same, except the colour scheme will be reversed, matching the system settings the user has chosen.

Of course, you can add more fancy stuff as well, maybe you want to change the font-weight because light disappears a bit on a dark background with your chosen fond? Or you can change the entire theme depending on a user’s system settings. I personally think that goes against some tenets of user-centered design, especially the concept of shared experiences, but if you want to go nuts, go nuts.

Such standards necessitate some complexity, meaning if your browser uses a different colour scheme from your system, which one should be obeyed? Thankfully Sara Soueidan did some investigating and discovered that the nearer context (such as the browser) overrules the further context (such as the OS).

Another interesting thing you might discover while implementing, is just how many extra declarations you have for colours. Don’t forget, you’ll need to invert each colour declaration when preferences via CSS media query, so if you’ve set the same colour on your headings, your body, your paragraph tags, your ordered and unordered lists, you might have to create inverted versions of them all. Is it better to just have one body declaration for a main colour?