Creating a Dark Theme Slider For Your Website with HTML, CSS, JavaScript, and Local Storage

The JavaScript Today blog was without a dark theme for awhile. We promised ourselves we would focus on creating content before developing new features on the site. Well, we hit our goal of 100 articles awhile back, so we’ve been doing some development work on the site, including introducing a dark theme toggler.

In this article, we’re going to show you how to create one for your own website as well. We’ll use Vanilla JavaScript, HTML, some CSS, and LocalStorage.

P.S. We’d love your feedback. Let us know what you think in the comment section below. Have a suggestion? Please do share! :D

Creating the toggle element

Before we write any JavaScript, we need some element on the DOM (Document Object Model) to actually target. In our case, that’s going to be a <input> element with a type attribute set to checkbox, and a class and id with the same.

We’re also going to make use of the Fontawesome CDN, in order to use the sun and moon icons within our toggler. We included it within the <head></head> tags down below.

<!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>Dark Theme Toggle</title>
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
      integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />
  </head>
  <body>
    <div class="dark-mode-toggle">
      <input type="checkbox" class="checkbox" id="checkbox" />
      <label for="checkbox" class="checkbox-label">
        <i class="fas fa-moon"></i>
        <i class="fas fa-sun"></i>
        <span class="ball"></span>
      </label>
    </div>
  </body>
</html>

Now we have the structure of the toggler. It should look something like this:

Dark Theme skeleton

So, we know our icons have been properly imported, and the HTML is being rendered as it should be (for now). Of course this simple checkbox could work, although obviously that would be a hideous thing to have on a modern website.

That’s where CSS comes in. Now, we’re not going to explain every line of CSS, as that would be tedious. Rather, we’re going to simply observe the changes being applied to the HTML. Let’s add the CSS!

💡 If your CSS skills are lacking, consider: CSS in Depth by Keith J. Grant. It covers the box model, grid layout, flexbox, and much more.

Once again, within the <head></head> tags, add the following code:

<head>
  <style>
    .checkbox {
      opacity: 0;
      position: absolute;
    }

    .checkbox-label {
      background-color: #333;
      width: 50px;
      height: 26px;
      border-radius: 50px;
      position: relative;
      padding: 5px;
      cursor: pointer;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .fa-moon {
      color: #f6f1d5;
    }

    .fa-sun {
      color: #f39c12;
    }

    .checkbox-label .ball {
      background-color: #fff;
      width: 30px;
      height: 30px;
      position: absolute;
      left: 2px;
      top: 2px;
      border-radius: 50%;
      transition: transform 0.2s linear;
    }

    .checkbox:checked + .checkbox-label .ball {
      transform: translateX(24px);
    }

    .dark-theme {
      background-color: #555;
    }
  </style>
</head>

After applying the CSS, our toggler should now look like this:

Dark Theme skeleton

A huge improvement over the previous image, we now have a little toggler with the sun and moon icons. However, the toggler doesn’t actually do anything useful yet, it just switches from side-to-side. Well, we want to dim the lights, eh? We’re going to need to finalize everything using JavaScript. Let’s get started working on the functionality.

First, we’ll need to add <script></script> tags, directly above the closing </body> tag, and add the following code:

<script>
  const userPrefersDark = false;

  function setThemePreference(prefersDark) {
    if (prefersDark) {
      document.body.classList.add("dark-theme");
    } else {
      document.body.classList.remove("dark-theme");
    }
  }

  setThemePreference(userPrefersDark);

  const checkbox = document.getElementById("checkbox");
  checkbox.checked = userPrefersDark;

  checkbox.addEventListener("change", (event) => {
    const isDarkMode = event.target.checked;
    setThemePreference(isDarkMode);
  });
</script>

Okay, great! It works. Kind of. If we refresh the page, the dark theme is no longer active, it remains in its original state. That wouldn’t be very kind to your users. We have one more, final step: adding persistance with local storage.

Don’t fret, it’s extremely simple!

We’ll simply need to change the following lines of code to include the use of local storage. Let’s do that:

// const userPrefersDark = false;
const userPrefersDark = localStorage.getItem("theme") === "dark";

// Other code 

checkbox.addEventListener("change", (event) => {
  const isDarkMode = event.target.checked;
  setThemePreference(isDarkMode);
  // Add the line below
  localStorage.setItem("theme", isDarkMode ? "dark" : "light");
});

Full code on GitHub

Conclusion

Congratulations! You’ve now got a pretty neat theme toggler button. Although, admittedly, it could use some styling work. You’ll also need to figure out how to include it in your own projects, but that shouldn’t be too difficult. If you have questions, or need some help, always reach out in the comments below.

Happy coding!

comments powered by Disqus

Related Posts

Unveiling the Fascination of the Collatz Conjecture: Exploring Sequence Creation with JavaScript

The Collatz Conjecture, also known as the 3x+1 problem, is a fascinating mathematical puzzle that has intrigued mathematicians for decades. It has sparked publications with titles such as The Simplest Math Problem Could Be Unsolvable, or The Simple Math Problem We Still Can’t Solve because it is, indeed, rather simple-looking.

Read more

The Art of Data Visualization: Exploring D3.js

Data is everywhere, flowing into our applications from various sources at an unprecedented rate. However, raw data alone holds little value unless it can be transformed into meaningful insights.

Read more

JavaScript’s Secret Weapon: Supercharge Your Web Apps with Web Workers

During an interview, I was asked how we could make JavaScript multi-threaded. I was stumped, and admitted I didn’t know… JavaScript is a single-threaded language.

Read more