Introducing ezToggle
This past weekend I created ezToggle - a simple way to add a theme toggle to your website using HTML, CSS, and basic JavaScript.
This is my first JavaScript success story but, for those of you that are looking for a simple way to add a light/dark theme toggle to your site this might be it!
Best of all, it includes minimal JavaScript so anyone should be able to use it.
var body = document.querySelector('body');
var bodyClass = body.classList;
var themeToggle = document.querySelector('#theme-toggle');
var footer = document.querySelector('.footer');
var light = document.querySelector('.light');
var dark = document.querySelector('.dark');
themeToggle.addEventListener('click', () => {
body.classList.toggle("light");
body.classList.toggle("dark");
themeToggle.classList.toggle("btn-light");
themeToggle.classList.toggle("btn-dark");
footer.classList.toggle("footer-light");
footer.classList.toggle("footer-dark");
});
Now then, if your footer doesn't change colors that's 3 lines you could remove from this - the real secret is in using CSS Variables. Let's go over how you can implement this in your website!
Getting Started
To begin you'll need the CSS & JS files which you can find in the GitHub Repo.
I have recently discovered CSS Variables and absolutely love them and knew they'd be perfect for this project - and every project moving forward.
If you don't know, a CSS Variable is a CSS Property that you can define once and call throughout the document. This makes it great for things such as colors, transitions, margin/padding, and much more! Whatever you repeat throughout your CSS can be turned into a variable.
This is particularly great for themes because you can change the colors in the variable you set once and they will be changed throughout the entire document.
/*--------------------Reusable Variables--------------------*/
:root {
/*--------------------Light Theme Variables (Default)--------------------*/
--light-theme-background-color: #eee;
--light-theme-darker-background-color: #ccc;
--light-theme-text-color: #333;
--light-theme-link-color: #ff6347;
--light-theme-link-hover-color: #fa2600;
}
More On CSS Variables
If you look at the code below you can see that I define the light theme in just 3 properties.
.light {
background: var(--light-theme-background-color);
color: var(--light-theme-text-color);
transition: var(--theme-change-timing);
}
Anywhere in the document I put var(--light-theme-text-color);
it will take on the same color which we defined as #fff;
in --light-theme-text-color: #333;
Why did I define the themes in 2 classes .light
and .dark
? Because I can simply add said class to the body
tag and BAM you've got your theme change.
Setup
HTML
First off, we need to apply a class of light to our body
tag:
<body class="light">
This sets the default theme to whatever is defined in our .light
class. If you want the default theme to be dark, just change it to <body class="dark">
.
CSS
There are a few steps involved in setting up the CSS. The first step is defining our CSS Variables in the :root
psudo-class. The reason for this is so that you don't have to repeat the variable in different elements on the page. When you declare them in :root
every element has access to them.
/*--------------------Reusable Variables--------------------*/
:root {
/*--------------------Light Theme Variables (Default)--------------------*/
--light-theme-background-color: #eee;
--light-theme-darker-background-color: #ccc;
--light-theme-text-color: #333;
--light-theme-link-color: #ff6347;
--light-theme-link-hover-color: #fa2600;
/*--------------------Dark Theme Variables--------------------*/
--dark-theme-background-color: #333;
--dark-theme-darker-background-color: #111;
--dark-theme-text-color: #eee;
--dark-theme-link-color: #00fa9a;
--dark-theme-link-hover-color: #00955b;
/*--------------------Other Variables--------------------*/
--link-hover-timing: all 0.25s ease-in-out;
--theme-change-timing: all 1s ease-in-out;
}
Next I created some classes for each theme. This included a general .light
and .dark
theme for the body, as well as a btn-light
and .btn-dark
, and .footer-light
and .footer-dark
.
/*--------------------Light Theme Styles (Default)--------------------*/
.light {
background: var(--light-theme-background-color);
color: var(--light-theme-text-color);
transition: var(--theme-change-timing);
}
.light a {
color: var(--light-theme-link-color);
}
.light a:hover {
color: var(--light-theme-link-hover-color);
}
.footer-light {
background: var(--light-theme-darker-background-color);
}
Just remember to apply any classes you create to the appropriate elements in your HTML file so they all get themed appropriately.
JavaScript
Firstly, we need to define our variables. You should do this at the top of the file so if you call these variables outside this theme toggle function they are available to them.
var body = document.querySelector('body');
var bodyClass = body.classList;
var themeToggle = document.querySelector('#theme-toggle');
var footer = document.querySelector('.footer');
var light = document.querySelector('.light');
var dark = document.querySelector('.dark');
If you choose not to style the footer you can just remove it, however, for ezToggle I made the footer darker than the rest of the page so I had to define it here so it can be called upon in the following function:
themeToggle.addEventListener('click', () => {
body.classList.toggle("light");
body.classList.toggle("dark");
themeToggle.classList.toggle("btn-light");
themeToggle.classList.toggle("btn-dark");
footer.classList.toggle("footer-light");
footer.classList.toggle("footer-dark");
});
The function listens for a click on the themeToggle button - the one that reads "Change Theme" on the website
Upon the button being clicked it first identifies the classes of the element it is attached to. Followed by .toggle
it then toggles (surprise) the specified class onto said element. It toggles between the light and dark classes.
Wrapping Up
Here's a summary of the steps needed to apply ezToggle to your website:
- Apply light or dark class to `body` in your HTML
- Define your CSS variables in the :root pseudo-class. Make sure you change, add, or remove any colors you need for your theme.
- Create, add, or remove any necessary classes for your themes and any items getting themed. Be sure to add these classes to the appropriate elements in your HTML file
- Define JavaScript Variables
- Enjoy your theme toggle!
I hope you enjoyed and understood my first technical blog. I'm looking forward to doing more of these in the future.
If you have any questions or issues using ezToggle please don't hesitate to reach out to me here on DEV or on Twitter.
Top comments (10)
You could so something like
What is the benefit of using dataset rather than a class?
The only benefit would be that you don't have to remove the old class simple override the dataset.
The main advantage of this method is that you don't need to change classes in several places. Simply change the dataset, or class if you prefer, on the body and everything else follows automatically.
I see! Interesting - I'm still (obviously) a novice in JS and definitely want to look more into this.
Thanks so much for reading and commenting, Andrew!
Along these lines, here's a custom element called <dark-mode-toggle> that initially respects the user's
prefers-color-scheme
user preference setting and also optionally allows for manually overriding it. Read more about it in this article (also mirrored here on DEV).Ooh thanks for the link! I'll check it out today after work as that sounds like the best solution so far. Thanks, Thomas!
You can also add "prefers-color-scheme" to identify if the user uses light or dark mode in his system.
developer.mozilla.org/en-US/docs/W...
Yes! This was on my list of things to add to it, actually. Thanks for the link - and reading!
Nice!
Thank you!