Fix the White Flash on Page Load When Using a Dark Theme on a Static Site

Published: Jan 17, 2021
Updated: Jun 13, 2022

I maintain a few Hugo themes, one of them named Cupper. Recently a GitHub issue was opened that described a white flash on page load when the dark theme was active. After some investigation, the bug was indeed real. A boy was it a tricky one.

Roughly speaking, these events were happening:

So, the user was seeing an early iteration of the page before the dark theme had been applied.

I needed a way to hide the page, then only show it once the dark theme had been applied. Also, the user experience had to remain smooth, or at least not jarring.

Here’s what I settled on: the user still sees the previous page until the newly requested page’s DOMContentLoaded event fires. This event sequentially calls two functions: the first handles the dark theme logic, the seconds shows the page.

Step 1 #

Use inlined CSS in the <head> to immediately hide the <body>.

<style>
  body {
    visibility: hidden;
    opacity: 0;
  }
</style>

Step 2 #

Show the <body> only after the dark theme is applied. Put the JS <script> at the bottom of the <body>.

function showTheme() {
  // Check Local Storage then apply dark theme if it's active
}

function showContent() {
  document.body.style.visibility = 'visible';
  document.body.style.opacity = 1;
}

window.addEventListener('DOMContentLoaded', function () {
  showTheme();
  showContent();
});

Step 3 #

On the off-chance the user has JavaScript disabled, still show the page. Put the <noscript> at the top of the <body>.

<noscript>
  <style>
    body {
      visibility: visible;
      opacity: 1;
    }
  </style>
</noscript>