Search code examples
javascriptcssbackground-colorcolor-scheme

Change div background color automatically when color-scheme changes


I'm using 3 radio buttons to switch color-schemes (automatic depending on system, light, and dark) and setting several css variables that will change my website's colors automatically on color-scheme changes. It works on the css-controlled div, but the problem is, when I get these variables into my js, the changes don't occur automatically upon radio button presses. I may need some kind of listener, but I don't know how to do that.

Here's what I've attempted.

<html>
  <head>
    <style>
      html {
        --background-light : #F5F5F6;
        --background-dark  : #1D1D1F;
      }

      :root {
        color-scheme: light;
        --background : var(--background-light);
      }

      @media (prefers-color-scheme: dark) {
        :root {
          color-scheme: dark;
          --background : var(--background-dark);
        }
      }

      [color-scheme="light"] {
        color-scheme : light;
        --background : var(--background-light);
      }

      [color-scheme="dark"] {
        color-scheme : dark;
        --background : var(--background-dark);
      }

      .mydivs {
        width : 100vw;
        height : 100vh;
      }

      #change-with-css {
        background : var(--background);
      }
    </style>
  </head>

  <body>
    <form id="color-scheme">
      <div>
        <input checked type="radio" id="auto" class="toggler" name="theme" value="auto"/>
      </div>
      <div class="color-boxes">
        <input type="radio" id="light" class="toggler" name="theme" value="light"/>
      </div>
      <div class="color-boxes">
        <input type="radio" id="dark" class="toggler" name="theme" value="dark"/>
      </div>
    </form>

    <div id="change-with-css" class="mydivs"></div>
    <div id="change-with-js" class="mydivs"></div>
    <script>
      const switcher = document.querySelector("#color-scheme");
      const doc = document.firstElementChild;
      const setTheme = (theme) => doc.setAttribute("color-scheme", theme);
      switcher.addEventListener("input", (e) => setTheme(e.target.value));

      const myJsDiv = document.querySelector("#change-with-js");
      const myDivBg = getComputedStyle(document.body);
      myJsDiv.style.background = myDivBg.getPropertyValue("--background");
    </script>
  </body>
</html>

Kindly help me in vanilla js format if possible, thank you.


Solution

  • You set the style background in js on dom loaded,but when the radio button was pressing,you ditnt set the style again, so this is the difference between the css and js,and css always has more efficiency then js.

    <style>
      html {
        --background-light: #F5F5F6;
        --background-dark: #1D1D1F;
      }
      
       :root {
        color-scheme: light;
        --background: var(--background-light);
      }
      
      @media (prefers-color-scheme: dark) {
         :root {
          color-scheme: dark;
          --background: var(--background-dark);
        }
      }
      
      [color-scheme="light"] {
        color-scheme: light;
        --background: var(--background-light);
      }
      
      [color-scheme="dark"] {
        color-scheme: dark;
        --background: var(--background-dark);
      }
      
      .mydivs {
        width: 100vw;
        height: 100vh;
      }
      
      #change-with-css {
        background: var(--background);
      }
    </style>
    <form id="color-scheme">
      <div>
        <input checked type="radio" id="auto" class="toggler" name="theme" value="auto" />
      </div>
      <div class="color-boxes">
        <input type="radio" id="light" class="toggler" name="theme" value="light" />
      </div>
      <div class="color-boxes">
        <input type="radio" id="dark" class="toggler" name="theme" value="dark" />
      </div>
    </form>
    <!-- <div id="change-with-css" class="mydivs"></div> -->
    <div id="change-with-js" class="mydivs"></div>
    <script>
      const switcher = document.querySelector("#color-scheme");
      const doc = document.firstElementChild;
      const setTheme = (theme) => {
        doc.setAttribute("color-scheme", theme);
        const myJsDiv = document.querySelector("#change-with-js");
        const myDivBg = getComputedStyle(document.body);
        myJsDiv.style.background = myDivBg.getPropertyValue("--background");
      };
      setTheme('auto');
      switcher.addEventListener("input", (e) => setTheme(e.target.value));
    </script>