How to add multiple themes to your website with CSS and JS

Featured on Hashnode

I've been working on my portfolio website of late and wanted to add the "theme switch" where users get to select whether they want to view my website in dark mode or light mode. While working on that, I realized this can be extended to not just two, but as many themes as you'd like. Pretty cool, eh? Let's see how we can do that.

First, take a look at what it'll look like:

This is the light mode:

light-mode.PNG

And this is the dark mode:

dark-mode.PNG

And the theme switch is in the right top corner

First of all, let's define all your CSS in one file, and the CSS variables for the colors we want to change in another file. Let's call the one with all the CSS as our style.css and the ones with dark theme colors as dark-variables.css and likewise the one with light theme colors as light-variables.css

Let's take a look at the two files now:

light-variables.css:

:root {
    --background: antiquewhite;
    --font: #242526;
}

dark-variables.css

:root {
    --background: #242526;
    --font: antiquewhite;
}

That's great. Now, let's add them to our index.html like this. Note that the link for variables file has an id stylesheet. We will be using this later:

  <link id="stylesheet" rel="stylesheet" href="dark-variables.css" />
  <link rel="stylesheet" href="style.css" />

Here, I want the users to land on the dark-themed page by default and they can change it to the light theme if they want to. If you want it the other way, you can change the first stylesheet to light-variables.css like below:

<link id="stylesheet" rel="stylesheet" href="light-variables.css" />
<link rel="stylesheet" href="style.css" />

Next, we need to add an event listener to the theme switch button. Let's first look at what that button looks like:

 <div id="theme-switch" class="theme-switch">
          <div id="theme-icon" class="fas fa-moon"></div>
 </div>

It's basically a div with id theme-switch that contains another div with id theme-icon which basically uses font awesome icons.

Now, let's add the event listener. What we need to do here is add a click event listener to trigger the theme switch function.

Let's break that down into smaller chunks now:

  • Let's get the theme-button first:
const themeButton = document.getElementById('theme-switch')
  • Now, let's add the event listener to trigger the theme switch function:
themeButton.addEventListener('click', themeSwitch)
  • Now, let's define the themeSwitch function bit by bit. First, let's get the stylesheet that is attached to the page currently:
const stylesheet = document.getElementById('stylesheet')

Remember we gave the id "stylesheet" to the variables file? That's what we are getting here.

  • Next, let's check the href associated with the stylesheet. We can do that like:
const currentStyle = stylesheet.href
  • Now, that we have the href, we can check which style is currently active and change to the other one. Let's do that:
   if (currentStyle.indexOf(lightTheme) !== -1) {
        stylesheet.href = darkTheme
        themeIcon.classList.remove(lightIcon)
        themeIcon.classList.add(darkIcon)
    }
    else {
        stylesheet.href = lightTheme
        themeIcon.classList.remove(darkIcon)
        themeIcon.classList.add(lightIcon)
    }
  • If you've noticed that we are removing and adding another class there, you are correct. That's the icon itself which we want to change when the theme is changed. So, for the light theme, we want the icon to be a moon to indicate that the users can click that button to switch to the dark theme, and for the dark theme we want the icon to be a sun to indicate that they can switch to light theme.

  • This is what the function looks like in the end. Notice the extra declarations there? I just prefer to assign variables to everything. That's my personal preference :)

function themeSwitch () {
     const darkIcon = "fa-sun";
     const lightIcon = "fa-moon";
     const lightTheme = "light-variables.css";
     const darkTheme = "dark-variables.css";
    if (currentStyle.indexOf(lightTheme) !== -1) {
        stylesheet.href = darkTheme
        themeIcon.classList.remove(lightIcon)
        themeIcon.classList.add(darkIcon)

    }
    else {
        stylesheet.href = lightTheme
        themeIcon.classList.remove(darkIcon)
        themeIcon.classList.add(lightIcon)   

    }

}

There it is! We have a website that supports multiple themes! If you want to add more themes, you can just add more buttons and add an event listener to each one. Each of these buttons can have their stylesheet with the colors of your choice. šŸ˜Ž

If you liked this article and want to know more about the stuff I am building, let's stay in touch on Twitter where I regularly post about things I am working on ā¤

Lucky Victory Chukwuede's photo

nice article,I love the way you declared js variables for almost everything.

John Francis Cortez's photo

This is so AWESOME!

Catalin Pit's photo

I always wondered how you could add multiple themes (dark and light) to your website.

Thanks for this great article, Tejansh Rana! šŸ‘

Tejansh Rana's photo

Thanks Catalin Pit! Iā€™m glad you found this useful :)