The theme for week #12 of the Weekly Coding Challenge is:
Toggle
A toggle (or a switch) is a component which allows you to change a state / a boolean value from true to false and vice-versa. It is basically a checkbox
, but we are going to hide it and display a nicer version of a toggle instead by using a label
. 😄
Furthermore, in this article we’re going to build a Dark/Light theme toggle:
https://codepen.io/FlorinPop17/pen/ZNqKVM/
The HTML
As mentioned above, we need a checkbox
(basically an input
with type="checkbox"
) which we’ll hide and a label
which will remain visible and it will be styled to look like a toggle (more about these in the CSS section below).
We’ll also wrap these elements with a div
in order to keep the code more structured.
<div class="toggle">
<input type="checkbox" id="toggle" />
<label for="toggle"></label>
</div>
See the for
attribute on the label
? This is crucial to have because this binds the label
to the checkbox
with the same id (toggle
) and when we click on the label
it will trigger the on/off toggle on the checkbox
. Pretty neat, eh? 😉
The CSS
First, we’ll have to hide the checkbox
because it has a default styling that can’t really be changed so we are going to style the label
instead to look and behave as we want it to:
.toggle input[type='checkbox'] {
display: none;
}
.toggle label {
background-color: #777;
border: 2px solid #555;
border-radius: 50px;
cursor: pointer;
display: inline-block;
position: relative;
transition: all ease-in-out 0.3s;
width: 100px;
height: 50px;
}
Great! Now we have the oval look on the label
; next we’re going to use the ::after selector to style the circle which will go inside this oval:
.toggle label::after {
background-color: #555;
border-radius: 50%;
content: ' ';
cursor: pointer;
display: inline-block;
position: absolute;
left: 2px;
top: 2px;
transition: all ease-in-out 0.3s;
width: 42px;
height: 42px;
}
We have the styling for the unchecked state. Now let’s style the checked state.
Let’s change the background
and the border
colors on the label
and the ::after
selector (the circle) we are going to move it from left (unchecked state) to the right (checked state) plus we are also changing the background-color
for it too.
In order to do that we’ll use two selectors:
- the :checked selector on the
input
- this will tell us whether it is checked or not - the
~
or the sibling selector - this will help us target thelabel
tag which comes after ourcheckbox
.toggle input[type='checkbox']:checked ~ label {
background-color: #00a0fc;
border-color: #006dc9;
}
.toggle input[type='checkbox']:checked ~ label::after {
background-color: #0054b0;
transform: translateX(50px);
}
Awesome! 😎 Now we finished the HTML and CSS for the toggle. Next, let’s play a little bit with JavaScript in order to add and remove a class (.dark-theme
) from the body
tag. You’ll see in a moment why we are doing this…
The JavaScript
const toggle = document.getElementById('toggle');
const body = document.body;
toggle.addEventListener('input', e => {
const isChecked = e.target.checked;
if (isChecked) {
body.classList.add('dark-theme');
} else {
body.classList.remove('dark-theme');
}
});
As you can see, depending on the checked
value of the toggle
(or checkbox
as mentioned above… These terms are interchangeable in our case) we are adding or removing the .dark-theme
class from the body
.
This can be used now to add some styling on the body
depending whether or not it has that class.
Some more CSS
Let’s say that by default the body
has a light background-color
, something like:
body {
background-color: #f5f7fa;
}
Now, we can target the body
with a class of .dark-theme
and change the color to a darker grey:
body.dark-theme {
background-color: #333;
}
This is just a simple example, but in the Codepen that I created you can see that I also added a little bit of text and I’m also changing that text’s color based on the value of the toggle
. 👍
Conclusion
Now you know how to create a basic dark/light theme toggle. 😃 You can go a step further and add multiple elements on the page (a navbar, sections, a footer, buttons, links, etc) and change their aspect based on the value of the toggle
(light or dark… on or off…). Pretty cool, eh? 😉
Can’t wait to see what you are going to create!
As always, make sure you share it with me!
Happy Coding! 😇