How to handle color scheme from default system to user controlled dark or light mode

Base on the system settings of the user, I got the dark or light scheme working with CSS.

Also interestingly, I added three switches to let the user choose light or dark mode and — even come back to system mode.

But, I found it very difficult to implement this in JavaScript. I don’t even know where to start. I am CSS writer.

Currently, it will automatically work base on your system scheme. And you can also use firefox dev tool to switch from light to dark mode.

Here’s the rest of the code, thanks

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Color Scheme</title>
  <style>


:root {
  --ref-black: #000000;
  --ref-white:#ffffff;

  color-scheme: light dark;
}


@media (prefers-color-scheme: light) {
  :root {
    --canvas: var(--ref-white);
    --canvas-text: var(--ref-black);
    --button-color: var(--ref-black);
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --canvas: var(--ref-black);
    --canvas-text: var(--ref-white);
    --button-color: var(--ref-white);
  }
}


body {
  margin: 76px;
}
.cp-theme-switcher {
  position: relative;
  display: flex;
  align-items: center;
  width: 72px;
  height: 20px;
  border-radius: 50px;
  border: 2px solid var(--button-color);

  
}

.cp-theme-switcher:hover {
  border-color: var(--button-color);
}


.cp-theme-switcher__button {
  position: absolute;
  border: none;
  background: white;
  border-radius: 100%;
  border: 2px solid var(--button-color);
  width: 32px;
 height: 32px;
 display: flex;

align-items: center;
  justify-content: center;
  cursor: pointer;
  appearance: none;
  opacity: 0;

  
}


.cp-theme-switcher__button[aria-pressed="true"] {
    opacity: 1;
}


.cp-theme-switcher__icon {
 width: 16px;
 height: 16px;
}


  .cp-theme-switcher__button--dark {
    left: -2px;
  }
  
  .cp-theme-switcher__button--system {
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    
  }
  
  .cp-theme-switcher__button--light {
    right: -2px;
  }

  .ut-visually-hidden {
  position: absolute !important;
  overflow: hidden !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  border: 0 !important;
  margin: 0 !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
}
  </style>
</head>
<body>

  <div class="cp-theme-switcher" role="group" title="Select a color scheme">
    <button data-color-scheme="dark" class="cp-theme-switcher__button cp-theme-switcher__button--dark" type="button" aria-pressed="false" title="Dark color scheme">
        <svg 
            xmlns="http://www.w3.org/2000/svg" 
            width="16" 
            height="16" 
            class="ob-icon cp-theme-switcher__icon" 
            viewBox="0 0 16 16"
            focusable="false"
            aria-hidden="true"
        >
            <path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278zM4.858 1.311A7.269 7.269 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.316 7.316 0 0 0 5.205-2.162c-.337.042-.68.063-1.029.063-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286z"/>
        </svg>
        
        <span class="ut-visually-hidden">Dark color scheme</span>
    </button>
  
    <button data-color-scheme="system" class="cp-theme-switcher__button cp-theme-switcher__button--system" type="button" aria-pressed="true" title="System color scheme">
      <svg 
      xmlns="http://www.w3.org/2000/svg" 
      width="16" 
      height="16" 
      class="ob-icon cp-theme-switcher__icon" 
      viewBox="0 0 16 16"
      focusable="false"
      aria-hidden="true"
  >
      <path d="M3.204 5h9.592L8 10.481 3.204 5zm-.753.659 4.796 5.48a1 1 0 0 0 1.506 0l4.796-5.48c.566-.647.106-1.659-.753-1.659H3.204a1 1 0 0 0-.753 1.659z"/>
  </svg>
        
        <span class="ut-visually-hidden">System color scheme</span>
    </button>
  
    <button data-color-scheme="light" class="cp-theme-switcher__button  cp-theme-switcher__button--light" type="button" aria-pressed="false" title="Light color scheme">
      <svg 
      xmlns="http://www.w3.org/2000/svg" 
      width="16" 
      height="16" 
      class="ob-icon cp-theme-switcher__icon"
      viewBox="0 0 16 16"
      focusable="false"
      aria-hidden="true"
      >
          <path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
      </svg>
        
      <span class="ut-visually-hidden">Light color scheme</span>
    </button>
  </div>

    <h1>
     How to handle color scheme from default system to user controlled dark or light mode 
    </h1>

    <p>
      Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nostrum consequuntur veniam modi optio, nulla suscipit molestiae aut. Alias suscipit porro obcaecati veritatis maiores optio doloribus est non! Exercitationem, consectetur ullam.
    </p>

    <p>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Numquam, odit accusantium vel nemo, atque quisquam asperiores, aliquam maiores amet aperiam reprehenderit? Quo illum perspiciatis, minus quibusdam adipisci provident ex ratione!
    </p>

  
</body>
</html>