« Previous | Next »

Light/Dark Mode Switcher

08 Nov 2022

I've implemented a light/dark mode switcher for this site. As mentioned in the previous post, the dark mode is Bulmaswatch Cyborg with some customizations. For the light mode, I use Bulmaswatch Default, with equivalent customizations.

The dark-mode CSS file is named dark.bulmaswatch.min.css, and the light-mode CSS file is light.bulmaswatch.min.css. In the HTML head, the CSS link now gets an ID (cssmode):

<link rel="stylesheet" type="text/css" href="/css/dark.bulmaswatch.min.css" id="cssmode"/>

Following are the Javascript functions that set the mode. The code should be self-explanatory:

function setMode(mode) {
    localStorage.setItem('cssmode', mode)
    document.querySelector('#cssmode').setAttribute('href', `/css/${mode}.bulmaswatch.min.css`)
}
function setLightMode() {
    setMode('light')
}
function setDarkMode() {
    setMode('dark')
}
function setDefaultMode() {
    cssmode = window.matchMedia('(prefers-color-scheme: dark)')
    setMode(cssmode.matches ? 'dark' : 'light')
}

When the HTML page is loaded, the following Javascript snippet sets the mode to a previously-stored setting, or the user's default, as the case may be:

cssmode = localStorage.getItem('cssmode')
if (cssmode !== null) {
    setMode(cssmode)
} else {
    setDefaultMode()
}

The user interface uses Bulma's dropdown behind a navbar-button. The entire mode switching menu code looks like this:

  <div class="navbar-item">
    <div class="dropdown is-hoverable" id="theme-menu">
      <div class="dropdown-trigger">
        <button class="navbar-button" aria-haspopup="true" aria-controls="dropdown-menu">
          <span>Theme</span>
          <span class="icon is-small"><i class="fas fa-angle-down" aria-hidden="true"></i></span>
        </button>
      </div>
      <div class="dropdown-menu" id="dropdown-menu" role="menu">
        <div class="dropdown-content">
            <a class="dropdown-item" onclick="setDefaultMode()">
              <i class="fa-solid fa-circle-half-stroke"></i>
              <span>OS Default</span>
            </a>
            <a class="dropdown-item" onclick="setLightMode()">
              <i class="fa-solid fa-sun"></i>
              <span>Light</span>
            </a>
            <a class="dropdown-item" onclick="setDarkMode()">
              <i class="fa-solid fa-moon"></i>
              <span>Dark</span>
            </a>
        </div>
      </div>
    </div>
  </div>
Tags: content management