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 {
  /* system schema */
  --background-primary: #f8f8f8;
  --background-secondary: #c0c0c0;
  --border-primary: #808080;
  --text-primary: #000;

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

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

/* automatic dark mode */
@media (prefers-color-scheme: dark) {
  :root {
    /* 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 {
    /* 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 {
  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);
  background: var(--background-secondary);
  padding: 1rem;
  border-radius: 4.33px;
  border: 1px dashed var(--border-primary);
}

.box .inner p {
  margin-bottom: 1rem;
}

.box .inner select {
  margin-bottom: 0.75rem;
}

JavaScript

document.addEventListener("DOMContentLoaded", function(event) {
  // Check for preference or previous setting.
  checkUserPreference();
});

// Get the select element.
const selectEle = document.getElementById('selectSchema');

// Watch the select element for change.
selectEle.addEventListener('change', function() {
  themeSchemaSetting();
});

// Check for user preference.
function checkUserPreference() {

  // Check to see if storage is set if not initialise.
  if (!localStorage.hasOwnProperty('currentSchema')) {
    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 || prefersLightSchema.matches) {
      selectEle.selectedIndex = 0; // Set system in select.
    } else {
      selectEle.selectedIndex = 2; // Set light in select.
    }
  }
  // Set the schema.
  themeSchemaSetting();
}

// Set the schema.
function themeSchemaSetting(currentSchema) {

  // Set & retreive local storage.
  selectValue = selectEle.value;
  localStorage.setItem('currentSchema', selectValue);
  currentSchema = localStorage.getItem('currentSchema');

  // debug log
  console.log("Select Value:", selectValue);
  console.log("Storage Schema:", currentSchema);

  // set theme based on set storage
  switch (currentSchema) {
    case 'systemSchema':
      // set light schema.
      console.log("Theme is system.");
      break;
    case 'lightSchema':
      // set dark schema.
      console.log("Theme is Light.");
      break;
    case 'darkSchema':
      // let the system decide.
      console.log("Theme is Dark.");
      break;
    default:
      // default schema developer preference.
      console.log("Theme is default. (Light)");
  }
}