0

On this website https://maruko.it there are two buttons on the lower-left corner. Their purpose is to change the webpage's theme when clicked and save the selected theme for the user in the local storage.

index.html

<head>
...
  <script defer src="/scripts/app.js"></script>
  <link rel="stylesheet" href="/styles/style.css">
...
</head>

<body id='mybody' class='dark-mode'>
  ...
  <span id="v">v1.1 | 
    <span>
      <button id="light-mode">☀️</button>   <!-- changes to light theme -->
      <button id="dark-mode"></button>    <!-- changes to dark theme -->
    </span>
  </span>
  ...
</html>
...

When one of the buttons is clicked, a CSS class gets 'activated' (the 'body' attribute 'class' is changed to either 'dark-mode' or 'light-mode'):

style.css

/* gets activated when button clicked */

:root {
    --white: white;
    --black: black;
}

.dark-mode {
    color: var(--white);
    background-color: var(--black);
}

.light-mode {
    color: var(--black);
    background-color: var(--white);
}

thanks to the following javascript:

app.js

const darkButton = document.getElementById('dark-mode');
const lightButton = document.getElementById('light-mode');
const body = document.body; // won't work without 'defer' attribute

// apply cached on reload
const theme = localStorage.getItem('theme');

if (theme) {
    body.classList.add(theme);
}

// button event handlers
darkButton.onclick = () => {
    body.classList.replace('light-mode', 'dark-mode');
    localStorage.setItem('theme', 'dark-mode');
};

lightButton.onclick = () => {
    body.classList.replace('dark-mode', 'light-mode');
    localStorage.setItem('theme', 'light-mode');
};

On the website you can clearly see that when clicked, the theme changes and gets saved to local storage (on Firefox, check the 'Storage' tab) but there's a catch: if the user selected the 'light-theme', on reload there's always going to be a flash of the 'dark-theme'. The 'body' has now the following attributes:

<body id="mybody" class="dark-mode light-mode">    <!-- now it has both! -->

This is clearly not the intended behavior: it looks like the 'light-theme' gets effectively set on the 'body' but only after 'dark-mode'.

Could you please guide me to the right solution / steps to eliminate the problem?

Mark
  • 21
  • 5
  • The "flash of dark-theme" is normal because it takes time for the browser to execute your JS. – Michael M. Sep 18 '22 at 18:54
  • @Michael M. What would a more appropriate approach be? The black flash is really annoying. – Mark Sep 19 '22 at 14:58
  • You might want to look at [this question](https://stackoverflow.com/questions/9550760/hide-page-until-everything-is-loaded-advanced) and it's answers, but I'm not sure this could be fast enough either. I'd still try it out though. – Michael M. Sep 19 '22 at 16:48
  • Tried it, but no luck. I also tried removing the transition but nothing. I just wanted to implement a simple theme switch, but I guess it is not as easy as the other websites make it look. – Mark Sep 19 '22 at 18:57

0 Answers0