Dark mode for the ages

They say projects are not finished until you write about them. So here we go.

Last night I was still up and awake at 2 am. I opened this website and ... BOOM ... bright light in my eyes. I do like this site's simple colorscheme, but when everything around you is dark it does kinda burn in your eyes. So I did what anyone who can't sleep at that hour does: I went on the internet, looked up how to change colors in CSS and implemented a theme toggle on my website (Look for the sun or moon on the top right!)

There's many articles on this topic, the one I found was The simplest CSS variable dark mode theme by Luke Lowrey.

My site is a very simple plain ol' HTML & CSS page. I use Writ as the base style and provide just a few things on top in my style.css. The colors are now defined like this:

:root,
html[data-theme='light'] {
  --main-bg-color: white;
  --text-color: #111;
  --alt-text-color: black;
  --code-bg: rgba(0,0,0,.05);;
  --border-color: rgba(0,0,0,.05);
  --link-color: #00e;
  --link-color-visited: #60b;
  --inline-code: #111;
}

html[data-theme='dark'] {
  --main-bg-color: #111;
  --text-color: #b3b3b3;
  --alt-text-color: #999999;
  --code-bg: #ccc;
  --border-color: #414141;
  --link-color: #478be6;
  --link-color-visited: #c988ff;
  --inline-code: #323232;
}

and then used with var(--main-bg-color) further below.

The theme toggle button requires a bit of JavaScript, which I straight out copied from Luke's blogpost (and put into theme.js).

var toggle = document.getElementById("theme-toggle");

var storedTheme = localStorage.getItem('theme') || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
if (storedTheme) {
    document.documentElement.setAttribute('data-theme', storedTheme)
}

toggle.onclick = function() {
  var currentTheme = document.documentElement.getAttribute("data-theme");
  var targetTheme = "light";

  if (currentTheme === "light") {
    targetTheme = "dark";
  }

  document.documentElement.setAttribute('data-theme', targetTheme)
  localStorage.setItem('theme', targetTheme);
};

It stores the user's preference in local storage and defaults to the system's prefered color scheme (see prefers-color-scheme).

Once I had it all in place I realized I've been testing the colors with my macOS' Night Shift mode on. Oh well, looks good with it on, looks still decent with it off I guess. The dark theme is not perfect and probably could use a bit more contrast. Code blocks look odd as they are essentially still light mode (just slightly dimmed), because the current code syntax highlighting does the styling inline and so it's a bit hard to overwrite that in the external CSS. But I decided it's better to ship the 80% solution then never get to shipping at all.