A light and dark theme with localStorage

Tonight I decided to add a dark theme to my website, I wanted to do this because I like using localStorage and seeing what I can make with it. I wanted to do it as simple as possible and with zero dependencies.

I decided to use Emoji’s as the icons but I will probably switch this out in the future with a real icon. I used localStorage to determine if the user has already switched the theme previously when they’ve visited and I added a few lines of CSS to handle the background and font colours.

The HTML, pretty straight forward:

<div class="checkbox">
  <input id="theme" type="checkbox">
  <label for="theme"></label>
</div>

Nothing crazy going on here just your standard input with a label to trigger it (we hide the input in order to customise it).

The CSS for the checkbox, again nothing bonkers but could potentially be cleaned up in the future.

.checkbox {
  position: absolute;
  top: var(--base-gutter);
  right: var(--base-gutter);
}

.checkbox input {
  display: none;
}

.checkbox label {
  cursor: pointer;
}

.checkbox label:after {
  content: "🌌";
  font-size: 30px;
}

.checkbox input:checked + label:after {
  content: "🔆";
}

Next up is the Javascript, I’ve added comments to run you through it.

const theme = document.getElementById('theme')
const themeValue = JSON.parse(localStorage.getItem('darkTheme'))

// Check if the value exists and if it does add the `.dark` class!
themeValue === true ? document.documentElement.classList.add('dark') : document.documentElement.classList.remove('dark')

// Event listener for when the checkbox is clicked
theme.addEventListener('click', function () {
  // Set `darkTheme` in localStorage to true or false
  localStorage.setItem('darkTheme', theme.checked)

  // If it's checked add the `.dark` class else remove it
  theme.checked ? document.documentElement.classList.add('dark') : document.documentElement.classList.remove('dark')
})

// If the user has already selected their preference then update the checkbox on load
theme.checked = themeValue

The way I have set my codebase up is that it only uses two colours for literally everything (with a few random RGBA’s), this way I’m able to basically control this in the html tag i.e by just setting background: black and color: white.

If the .dark class is applied then I can pretty much just add this bit of CSS and everything goes dark:

.dark {
  background: var(--dark-theme-background);
  color: var(--dark-theme-text);
}

You made it! That is pretty much it, If you have any questions feel free to reach out here.