Dark and Light

REST EASY WEARY EYES

Saturday, Oct 3, 2020

Introducing Dark Mode

I have implemented theming of this website to allow you, the visitor, to dictate wheter you would like to see things in light or dark mode.

dark mode activation gif

It seems that more and more websites and applications (desktop and mobile) are respecting the user’s decision to choose a theme that suits them best. I personally prefer things in dark mode and have that reflected across all my devices. To me, it just feels better. At this point, I’m sure there are countless articles advocating this or that when it comes to light vs. dark mode. Accessibility, fatigue, power consumption are just a few of the many considerations when it comes to theming in UI/UX decisions and I was curious of how hard implementing dark mode would be.

Turns out: it wasn’t bad at all.

Making it work

The only changes I needed to make were

  • theme-specific assets
  • CSS custom properties for color theming
  • JavaScript to tie it all together

Fortunately, my website is small enough that the only asset I need to address is the site’s logo. The site favicon is a PNG image while every other instance of the logo are embedded SVG’s within an <img src=".."/> tag. I designed the logo using a vector art application on my iPad which made updating the fill and line colors very simple. I exported the necessary PNG’s and SVG’s and added them to the static assets for the site.

Next, I defined the following CSS custom properties to contain the palette that my site would use:

:root {
    --themecolor-emphasis: #FFB627;
    --themecolor-accent1: #D84727;
    --themecolor-main1: #eeecec;
    --themecolor-main2: #2c2929;
    --themecolor-white: #eeecec;
    --themecolor-black: #2c2929;
    
    /*truncated*/
}

And lastly, JavaScript runs a query to determine if the browser prefers light or dark mode

if (window.matchMedia('(prefers-color-scheme: dark)').matches) {handleDarkMode();}

function handleDarkMode() {
  //update favicon
  var favicon = document.querySelector('link[rel="icon"]');
  if (!favicon) { return };
  favicon.href="/img/favicon-dark.png"
  //swap CSS colors
  var root = document.documentElement
  var rootComputedStyle = getComputedStyle(root);
  var theme1 = rootComputedStyle.getPropertyValue("--themecolor-main1");
  var theme2 = rootComputedStyle.getPropertyValue("--themecolor-main2");
  root.style.setProperty("--themecolor-main1", theme2);
  root.style.setProperty("--themecolor-main2", theme1);
  //update logo
  var logo = document.querySelector("#logo");
  if (logo) {logo.src = "/img/logo-dark.svg";}
}

Conclusion

This was a very simple solution to incorporating a dark theme. This approach, using vanilla CSS and JavaScript might not scale very well for large websites with more intricate and nuanced themes and large pools of static assets. In the end though, it was a good exercise and I’m thoroughly happy with the results.