Zero's Ivory Tower
  • 简体中文 ○
  • English ⦿
  • Français ⨂
RSS feed ⊠
Zero's Ivory Tower
(●’◡’●)ノ
MATHEMATICS
Math Noes
Math Stories
NON-MATHMATICS
Journal
Literature
Memos
RECORD
Books Read
Films Watched
ABOUT
About Me
About The Site
©2019-2025 All Right Reserved.
Fix the White Flash on Page Load When Using a Dark Mode on a Static Site - Build a Theme
August 27, 2021 - 631 words

The problem ¶

This Hugo theme I wrote have had a problem. It defaults to the light mode, but if you switch to the dark mode1, then when loading a new page it will first render the light mode and then automatically switch to the dark, looks like it flashes white a little bit. I thought all the static sites have to face this problem, until one day I found some healthy themes, for instance, PaperMod⧉. So, there must be a way to solve this.

I searched this on the internet. There is an article Fix the White Flash on Page Load When Using a Dark Theme on a Static Site⧉ by the maintainer of theme Cupper⧉. I tried their solution. In Chrome, it indeed works; but in Firefox it doesn’t. Firefox will render visibility: hidden; opacity: 0; to a whole blank page, and only after DOMContentLoaded happens showContent() function will show the content. Means: the page still flashes. Before it flashes the light mode, now it flashes the blank page. Just as bad as before.

I think the difference between Firefox and Chrome is because the developers of Chrome used magic, they tried their best to bring Chrome users a better experience. And this covers up the real problem for the Hugo theme developers who use Chrome.

Find the cause ¶

The main idea is still to understand the process of how the browser render a page. Simply put:

  • You request for a page;
  • The browser download the entire HTML and save as DOM, then parse and render the page from top to bottom;
  • Stop parsing when encountering an external CSS or JavaScript file. Download it and then continue;
  • When encountering <style></style> or just loaded external styles, store them as CSSOM and re-render the influential part;
  • When encountering <script></script> or just loaded external scripts, stop parsing and run the scripts. Continue parsing and rendering after finish running them;
  • So on and so on until all the works are done.

The cause to the white flash problem is that I put the JavaScript for theme’s mode switching at the end of <body>, like this:

1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
    <body>
        <!-- lots of stuff…… -->

        <script src="changeTheme.js"></script>
    </body>
</html>

The solution ¶

The solution to this problem is quite simple, with two points:

    1. Put the script for theme’s mode switching into <head>, in order to determine the theme currently selected by the user before rendering the body;
    1. Upgrade the container for the theme to the entire <html>, i.e., from
1
2
3
4
<html>
    <body class="theme-container">
    </body>
</html>

to

1
2
3
4
<html class="theme-container">
    <body>
    </body>
</html>

This is because <body> has not been rendered at this time, and the only object that can be manipulated by the script in <head> is <html>.


Now the problem is completely solved, the complete code is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html class="theme-container">
    <head>
        <!-- lots of stuff…… -->

        <script>
            const themeContainer = document.querySelector(".theme-container");
            var theme = localStorage.getItem("theme");
            if (theme == "dark") {
                themeContainer.classList.add("dark");
            } else if (theme == "light") {
                themeContainer.classList.remove("dark");
            }
        </script>
    </head>

    <body>
        <!-- lots of stuff…… -->

        <script src="others.js"></script>
    </body>
</html>

  1. The approach to dark mode in this theme is CSS variable, see this tutorial⧉ for reference. ↩︎

See also

  1. No.1: Fix the White Flash on Page Load When Using a Dark Mode on a Static Site - Build a Theme (This one!)
  2. No.2: Make Hugo Invert Color for Images when Using a Dark Mode - Build a Theme

  • The problem
  • Find the cause
  • The solution