How to create a dark theme system in 5 minutes or less with vanilla JS.
Tags: html, css, tutorial, webdev
Published: 2020-10-17 05:56:01


A long time ago, in my old blog, I wrote an article called "How to create a dark theme system with jQuery". And I think this is the perfect moment to create a **simpler, cleaner and better dark system, free of jQuery**.

I use this same system (But expanded) **[on my own website](https://codedgar.me/)!** You can find all the code in [this GitHub repo.](https://github.com/codedgar/darkmode-in-5-minutes)
{% github codedgar/darkmode-in-5-minutes no-readme %}

To make the article simpler to read, I've cut up the article in chunks, check this out:

 - Intro - CSS variables.
 - The basics - Toggling classes.
 - Summing it up - Saving and retrieving the setting.

## Intro - CSS variables

CSS Variables are exactly what they sound like, variables, and this comes very handy for our system. It means that we can define **all the colors in one CSS class**, instead of nesting the colors that we are going to use all across our website.

Wrong

    .dark_mode>body{
    	background: #000;
    }

Nice

    .dark_mode{
    	--body_bg: #000;
    }



Using CSS variables prevents you from having to use child selectors, but rather use a class. This makes it easier to have even several themes and helps to have all of your colors defined in just one class.

This also means that you now will have to defined colors this way:



    :root{
    	--text-color: #000;
    	--body-bg: #fff;
    }
    body{
    	color: var(--text-color);
    	background: var(--body-bg);
    }




So, go ahead and find **every color you want to change in your CSS**, and do it this way. This is the perfect moment to open up the developer tools and **select the colors you want your website to have in dark mode and defined into a class called "dark_mode"**.

**You just did the intro, hooray!**

## The basics - Toggling classes.

Now that you have your CSS redefined, it's time to get into JS territory, are you ready? ***Let's do it***.

The main thing we need to do is create a button, and  retrieve it element, we can do that by just using a simple:

    document.querySelector('#theme_toggler');

 
Now that we have the element, we have to define it in order to add an event listener:

		
    let theme_toggler = document.querySelector('#theme_toggler');


Ok, so what do we do on our friend the theme_toggler? We need to add an event listener that toggles the class on our body tag, and that's pretty easy, we do it like so:

```
let theme_toggler = document.querySelector('#theme_toggler');

theme_toggler.addEventListener('click', function(){ 
    document.body.classList.toggle('dark_mode');
});
```

{% codepen https://codepen.io/Codedgar/pen/bGebbqj default-tab=js,result %}



As you can see in the example, is working kinda nicely!

"*Cool, it is ready? Can I leave? Could you let go my arm?*" Sadly the answer is *sort of, no and  no*... You see, it toggles the class, but if your user recharges the website or leaves and comeback, there's nothing telling the browser to store it, so you would have to click again... And again, and again. **Which takes us to our last step**!

## Summing it up - Saving and retrieving the setting.

Ok, now that we are toggling the class, we have just one step left, and that's saving the setting with our good buddy and pal, **localStorage**.

localStorage comes perfect in this kind of situations because it's simple to use. We just need to do **3 main things**:

 - Save the setting
 - Retrieving the setting
 - **BONUS**: Adding an event listener to the localStorage event

### Saving the setting
Let's start with saving the setting, and this is very simple:

		
    localStorage.setItem('website_theme' , 'dark_mode');

	

Here we're are setting the dark_mode, but not disabling it, to toggle the dark_mode on and off we need to do the following:

	

		
    if(document.body.classList.contains('dark_mode')){
    	localStorage.setItem('website_theme','dark_mode');
    }else{
    	localStorage.setItem('website_theme','default');
    }

	

This checks if the body element has the **dark_mode class**. If it doesn't it sets it to a **default class** theme.

### Retrieving the class

This is even simpler, we first need to verify if the item of the localStorage exists, and if it does we just apply the class that we saved on the localStorage, being **default** or **dark_mode**, then we call it as a function.

		
    function retrieve_theme(){
    	var theme = localStorage.getItem('website_theme');
    	if(theme != null){
    		document.body.classList.remove('default', 'dark_mode'); 
    		document.body.classList.add(theme);
    	}
    }
    retrieve_theme();



And that's pretty much it! If you reload the page, the theme will be saved! ***Now just a bonus, because you deserve it***.

### BONUS: Adding an event listener to the localStorage event.
Surprisingly enough, adding an event listener to the localStorage is fairly simple. And what does this do? This makes all of the tabs open of your page synchronized, **TLDR: Change it on one tab, and it's gonna change in all of them**.

Ok and how do we do that? Simple, we do it like this:


	

		
    window.addEventListener("storage",function(){
    	retrieve_theme();
    },false);


Piece of cake? Am i rite? That's all you need to know! And this is our final result:
{% codepen https://codepen.io/Codedgar/pen/yLJBzMZ default-tab=js,result %}

{% github codedgar/darkmode-in-5-minutes no-readme %}

## Conclusion
With dark themes becoming more and more popular, creating dark better dark themes with less code is great, and I hope you can add your amazing theme and make your website super cool. See ya around!