skip to Main Content

I would like to add a button for switching to darkmode and lightmode on my website.

I use var()’s in my css to control the color of my elements.
This is my code:

function loadMode() {
    const mode = localStorage.getItem('mode');
    if (mode === 'dark') {
        setDarkMode();
    }
}

// set darkmode
function setDarkMode() {
    document.documentElement.style.setProperty('--textColor', '#eaeaea');
    document.documentElement.style.setProperty('--backgroundColor', '#333333');
    document.getElementById('toggleMode').textContent = 'Wechsel zu Lightmode';
    localStorage.setItem('mode', 'dark');
}

// set lightmode
function setLightMode() {
    document.documentElement.style.setProperty('--textColor', '#313131');
    document.documentElement.style.setProperty('--backgroundColor', '#e0e0e0');
    document.getElementById('toggleMode').textContent = 'Wechsel zu Darkmode';
    localStorage.setItem('mode', 'light');
}

// toggle the color mode
function toggleMode() {
    const isDarkMode = localStorage.getItem('mode') === 'dark';
    if (isDarkMode) {
        setLightMode();
    } else {
        setDarkMode();
    }
}

// event listener for button
document.getElementById('toggleMode').addEventListener('click', toggleMode);

// load mode on site load
loadMode();

This script is loaded on the end of the webpage (this is the problem, I know, but how can I fix it?)
Now I have the problem that every time I go to a subpage the website is being loaded with the Light Colors and then switched to the dark colors which results in a quick, but very annoying color flicker effect.

How can I prevent this form happening? My website is build with php so sessions could work? Or cookies?

Thank you for helping!

I tried to put the function in the header but then the body element cant receive the color change because I think its not loaded yes(?)

2

Answers


  1. Chosen as BEST ANSWER

    I fixed it myself:

    Put part of the script in the :

    <script>
        (function() {
            const mode = localStorage.getItem('mode');
            if (mode === 'dark') {
                document.documentElement.style.setProperty('--textColor', '#eaeaea');
                document.documentElement.style.setProperty('--backgroundColor', '#333333');
            } else {
                document.documentElement.style.setProperty('--textColor', '#313131');
                document.documentElement.style.setProperty('--backgroundColor', '#e0e0e0');
            }
        })();
    </script>
    

    And put the rest of the code at the end of the body:

    <script>
    function loadMode() {
        const mode = localStorage.getItem('mode');
        if (mode === 'dark') {
            setDarkMode();
        }
    }
    
    function setDarkMode() {
        document.documentElement.style.setProperty('--textColor', '#eaeaea');
        document.documentElement.style.setProperty('--backgroundColor', '#333333');
        document.getElementById('toggleMode').textContent = 'Wechsel zu Lightmode';
        localStorage.setItem('mode', 'dark');
    }
    
    function setLightMode() {
        document.documentElement.style.setProperty('--textColor', '#313131');
        document.documentElement.style.setProperty('--backgroundColor', '#e0e0e0');
        document.getElementById('toggleMode').textContent = 'Wechsel zu Darkmode';
        localStorage.setItem('mode', 'light');
    }
    
    function toggleMode() {
        const isDarkMode = localStorage.getItem('mode') === 'dark';
        if (isDarkMode) {
            setLightMode();
        } else {
            setDarkMode();
        }
    }
    
    document.getElementById('toggleMode').addEventListener('click', toggleMode);
    
    // Load mode on page load
    loadMode();
    

  2. Make sure that your JavaScript is executed as soon as possible. It is always a good idea to have you JavaScript defined in the <head> element. You can add the defer attribute to the script tag to make sure that the code is executed before the DOMContentLoaded event. But having the inline JavaScript in the <head> will also do that.

    The event DOMContentLoaded is fired when the DOM is ready and you can start manipulating the DOM. When that happens you can set the (dark/light) mode. In the following example I removed a lot of the JavaScript. The less you manipulate the DOM, the better. And I rely on CSS to switch between the two different modes.

    In the example I comment out the code for localStorage, because it doesn’t work on StackOverflow.

    :root {
      --textColor: #313131;
      --backgroundColor: #e0e0e0;
    }
    
    :root:has(form[name="mode"] input:checked) {
      --textColor: #eaeaea;
      --backgroundColor: #333333;
    }
    
    body {
      color: var(--textColor);
      background-color: var(--backgroundColor);
    }
    
    form[name="mode"] input {
      display: none;
    }
    
    form[name="mode"] label {
      cursor: pointer;
      background-color: gray;
      border: thin black solid;
      border-radius: .2em;
      padding: .2em;
    }
    
    form[name="mode"] label::before {
      content: "Wechsel zu Darkmode";
    }
    
    form[name="mode"] label:has(input:checked)::before {
      content: "Wechsel zu Lightmode";
    }
    <html>
      <head>
        <script defer>
          document.addEventListener('DOMContentLoaded', e => {
            //document.forms.mode.dark.checked = localStorage.mode === 'dark';
            // test in the absence of localStorage:
            document.forms.mode.dark.checked = false;
            
            document.forms.mode.dark.addEventListener('input', e => {
              //localStorage.mode = e.target.checked ? 'dark' : 'light';
              // test in the absence of localStorage:
              console.log('mode is now:', e.target.checked ? 'dark' : 'light');
            });
          });
        </script>
      </head>
      <body>
        <form name="mode">
          <label><input type="checkbox" name="dark"></label>
        </form>
      </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search