Implementing a dark theme in jekyll

So breaking this down:

  • As you are using a static site generator, you can only apply the dark or light theme once a small piece of Javascript executes to determine and set the theme.
  • This is resulting in some delay/flash of content as the Javascript executes.

I think using a static site generator means that reading from localStorage and applying a theming class with Javascript is a perfectly good approach. As I see it, there are two possible approaches to minimising the flashing issue that don't involve changing the architecture away from a Jekyll site.

Execute the Javascript sooner, as the page content is loading:

Because the only DOM element that needs to have loaded is the <html> element itself, to which you can apply a theme class, you could put your 'critical' Javascript in a small script tag inside the <head>. i.e. just the 'theme-switching' line of code.

It should then execute straight away before the content loads.

Use CSS transitions to minimise the flash itself:

You could hide the page content while the <html> element has no theming class, and fade it in once one is applied like so:

html {
    opacity: 0;
    transition: opacity 1s;
}

html.light, html.dark {
    opacity: 1;
}

What you want, according to point 3,

Implement some kind of fade in/fade out when changing the visibility from hidden to visible

is --

CSS Transitions

Example usage to show ease-in effect whenever a CSS property change:

body {
  transition: background 1s ease-in, color 1s ease-in;
}
.dark {
  color: white;
  background: black;
}
<body>

  <p> Lorem Ipsum dolor sit amet... </p>

  <button onclick="document.body.classList.toggle('dark')">Change Theme</button>

</body>