Dark Mode Toggle

Dark Mode Toggle Testing

by Lewis ' Beaniie'

HTML

<div class="box">
  <div class="inner">
    <p>
      Dark Mode Toggle Testing
    </p>
    <!-- css colour mode select -->
    <div class="theme-switcher">
      <label for="selectSchema">
        <div class="select_container">

          <!-- select element -->
          <select class="select select-small" id="selectSchema" aria-label="Change color theme">
            <option value="systemSchema">System</option>
            <option value="lightSchema">Light</option>
            <option value="darkSchema">Dark</option>
          </select>

        </div>
      </label>
    </div>
  </div>
</div>

CSS

body {
  padding: 0;
  margin: 0;
  font-family: sans-serif;
  font-weight: 300;
  background: var(--background-primary);
}

:root {
  /* default schema */
  --background-primary: #f8f8f8;
  --background-secondary: #c0c0c0;
  --border-primary: #808080;
  --text-primary: #000;

  /* dark mode schema */
  --dm-background-primary: #000;
  --dm-background-secondary: #101010;
  --dm-border-primary: #404040;
  --dm-text-primary: #fff;

  /* light mode schema */
  --lm-background-primary: #fefefe;
  --lm-background-secondary: #c0c0c0;
  --lm-border-primary: #808080;
  --lm-text-primary: #000;
}

:root.dark-mode {
  /* dark mode schema - active */
  --background-primary: var(--dm-background-primary);
  --background-secondary: var(--dm-background-secondary);
  --border-primary: var(--dm-border-primary);
  --text-primary: var(--dm-text-primary);
}

:root.light-mode {
  /* dark mode schema - active */
  --background-primary: var(--lm-background-primary);
  --background-secondary: var(--lm-background-secondary);
  --border-primary: var(--lm-border-primary);
  --text-primary: var(--lm-text-primary);
}

/* automatic dark mode */
@media (prefers-color-scheme: dark) {
  :root.dark-mode {
    /* dark mode schema */
    --background-primary: var(--dm-background-primary);
    --background-secondary: var(--dm-background-secondary);
    --border-primary: var(--dm-border-primary);
    --text-primary: var(--dm-text-primary);
  }
}

/* automatic dark mode */
@media (prefers-color-scheme: light) {
  :root.light-mode {
    /* dark mode schema */
    --background-primary: var(--lm-background-primary);
    --background-secondary: var(--lm-background-secondary);
    --border-primary: var(--lm-border-primary);
    --text-primary: var(--lm-text-primary);
  }
}

.box {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  max-width: 400px;
  margin: 0 auto;
}

.box .inner {
  text-align: center;
  width: 500px;
  color: var(--text-primary);
...

JavaScript

localStorage.clear();

// Get the select element.
const schemaSelect = document.getElementById('selectSchema');
let selectedSchema = localStorage.getItem('selectedSchema');

// Check for previous instance if any.
if (selectedSchema) {
  schemaSelect.value = selectedSchema;
}

schemaSelect.onchange = function() {
  localStorage.setItem('selectedSchema', this.value);
  themeSchemaSetting();
}

// Initialise theme.
themeSchemaSetting();

// Set the schema.
function themeSchemaSetting() {

  let currentSchema = localStorage.getItem('selectedSchema');

  let htmlTag = document.querySelector('html');
  htmlTag.classList.remove('light-mode');
  htmlTag.classList.remove('dark-mode');

  // set theme based on set storage
  switch (currentSchema) {
    case 'lightSchema':
      // set light schema.
      console.log("Theme is Light.");
      htmlTag.classList.add('light-mode');
      break;
    case 'darkSchema':
      // let dark schema.
      console.log("Theme is Dark.");
      htmlTag.classList.add('dark-mode');
      break;
    default:
    
      // default schema let the OS decide.      
      const prefersDarkSchema = window.matchMedia("(prefers-color-scheme: dark)");
      const prefersLightSchema = window.matchMedia("(prefers-color-scheme: light)");
      // If user preference detected set system schema, else set light schema.
      if (prefersDarkSchema.matches) {
        htmlTag.classList.add('dark-mode');
      } else if (prefersLightSchema.matches) {
        htmlTag.classList.add('light-mode');
      }
      console.log("Theme is OS.");
  }
}