Adding Dark Mode to my Blog

When I transitioned this blog from WordPress over to Zola, I had to rewrite all my HTML and CSS for the new engine. At that point, dark mode support was a bit of a pain in the CSS. You needed to duplicate a lot of code, including the nested cascade. It just felt like a bit of a kludge.

I also hold some fairly strong, and occasionally controversial, opinions about dark mode, so I've been reluctant to add it to my blog. If you ever see me in person, ask me, and I'll let you know all about it, including physical demonstrations.

Anyway... back to business.

My main objection to the technical implementation of dark mode, was the @media query. It meant you had to repeat a large portion of CSS, inside the query, only with the colours changed.

body {
    background-color: #eee;
    color: #111;
}

@media (prefers-color-scheme: dark) {
  body {
    background-color: #111;
    color: #eee;
  }
}

This seemed wrong to my sensibilities, but luckily, times have moved on. Zola comes with a Sass/SCSS preprocessor, which makes it a little easier to adopt some DRY best-principles. It still left quite a bit of duplicate CSS, though, even with variable definitions. At least you only need to define the colours once, then you could re-use them all over your file.


$dark = #111;
$light = #eee;

body {
    background-color: $light;
    color: $dark;
}

@media (prefers-color-scheme: dark) {
  body {
    background-color: $dark;
    color: $light;
  }
}

In the intervening years, the standards have moved forward and native CSS has released the color-scheme property and light-dark function. In 2026, this is supported by every major browser and allows you to write your colour schemes in one place, then refer to them by their logical, contextual, variable names. This feels much more "CSS"-y to me than the other, older, implementations.

Back in the day, we moved away from HTML attributes across to CSS to break the semantic content of the document away from the styling. This seems like the same step, but breaking colours away from the layout.

:root {
    color-scheme: light dark;

    --bg-color: light-dark(white, #232);
    --fg-color: light-dark(black, white);
}

body {
    background-color: var(--bg-color);
    color: var(--fg-color);
}

Editor tooling for this has improved drastically over the past few years too. In JetBrains' editors, the line-number gutter is now annotated with colour swatches for both themes.

Screenshot from WebStorm showing CSS colour swatches in the line number gutter.

So there we go; against my better judgement, my website now supports dark mode. This is still very "beta", however, so if you spot something off or have some constructive feedback, please leave a comment.

2026-08-04

Leave a comment