Mini Challenge: Build a Dark Mode Button
Open the project folder
In our starter files, open the index.html page from this lessons folder:
04.Events-And-The-DOM > 16.Mini-challenge-create-a-dark-mode-button
Challenge
It’s now time to put the things we have learned in this section into practice. We will be building a simple website to toggle between light and dark mode.
Looking at the starter file contents, we just have some simple HTML:
<header>
<h1>Night Or Day</h1>
<button>☽</button>
<!-- <button>☼</button> -->
</header>
<hr />
<main>
<article>
<h3>New this week</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
molestiae at culpa similique ratione quibusdam!
<!-- ... -->
</p>
</article>
</main>
<aside>
<section>
<h3>Tags</h3>
<ul>
<li>seasonal</li>
<li>new</li>
<li>hot</li>
<li>sale</li>
</ul>
</section>
<!-- ... -->
</aside>
This is a basic website currently in light mode. Most of the above content is just filler. You will be focusing on the button element. The commented out button is just for reference to the sun icon if you want to toggle between the sun and moon icons (☽ ☼).
Among some basic styling, not the .dark class in the styles.css file:
.dark {
color: rgb(219, 219, 219);
background: rgb(44, 36, 36);
}
Steps
Test yourself by adding some JavaScript in the script.js file. The steps are:
- Listen for a click to the button.
- This will call a function when clicked.
- Use this function to add/remove the .dark class to the body when the button is clicked.
- The button innerHTML can then be toggled between the sun and moon icon (entity codes available in the index file).
If you feel confident, go ahead and try this. There is some additional help below if needed.
Extra help
Toggling like this involves checking if the dark mode has already been applied, then removing it. For this you can use an if statement which we have only briefly covered, and maybe a little bit of research too to get this one to work.
The contains method may be useful for this:
if (body.classList.contains('dark')) {
// ...
}
This contains method checks if a list contains a certain value, you do not have to use this, but you may find it useful as you go through the challenge. So don’t worry if you cannot complete this part, giving it a go on your own will really help you to remember the things you have learned so far.
Solution
Here is one way of completing this challenge, if yours looks different, that is fine too:
// script.js
// select button
const button = document.querySelector('button');
// add basic function
function toggleDarkMode() {
}
// add event listener
button.addEventListener('click', toggleDarkMode);
Next, the dark class from the CSS can be applied to the body:
const button = document.querySelector('button');
// 1. select body element
const body = document.querySelector('body');
function toggleDarkMode() {
// 2. add dark class
body.classList.add('dark');
}
This is the simpler part completed. Now we need to figure out a way to do the opposite and remove the dark class.
First, add an if statement:
function toggleDarkMode() {
// add if statement:
if () {
}
body.classList.add('dark');
}
We need to check if the dark class has already been applied, and for this we can use the contains method:
function toggleDarkMode() {
// 1. add to if statement:
if (body.classList.contains('dark')) {
// 2. remove the dark class
body.classList.remove('dark');
}
body.classList.add('dark');
}
Even with this, the toggle still won’t work. The reason why it won’t toggle is because of the last statement in our function. Here we are always applying the dark class at the end, so even when we remove it, it will again be re applied later in the code.
To resolve we can include the return keyword at the end of the if statement:
function toggleDarkMode() {
if (body.classList.contains('dark')) {
body.classList.remove('dark');
return;
}
body.classList.add('dark');
}
This will break out of the function when the if section runs, ignoring the remaining code. The remaining steps was to change the button's icon and the color:
function toggleDarkMode() {
if (body.classList.contains('dark')) {
body.classList.remove('dark');
button.innerHTML = '☽';
button.style.color = 'rgb(62, 62, 62)';
return;
}
body.classList.add('dark');
button.innerHTML = '☼';
button.style.color = 'aqua';
}
This is completed by changing the innerHTML and style property of the button.
The challenge is now complete!