In this tutorial, this is what we are going to be building:
Part of the reason why I am writing this, is because of the calculator challenge on frontendmentor.
I was working on the challenge and I came across this switch that is supposed to switch between the three themes of the calculator.
So I thought it would be a great idea to write a tutorial on how to do it because I know it’s not very straight forward and not everyone would get it easily.
And by the way, if you don’t know what frontendmentor is, it is basically a website that helps you improve your frontend development skills by providing real world projects to you so you can practice with.
If you have any problem coming up with what to build or really want to improve your skills as a frontend developer, then I really recommend you check them out. They’re really helpful.
So before we begin, I will like to mention that you need to have the basics of html, css and javascript in order to follow up properly; but I will still try my best to explain as much as possible.
So firstly, we need to create an index.html file with the following content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>tri-state toggle</title>
</head>
<body>
<div class="tri-state-toggle">
<input class="button" type="radio" name="toggle" id="one" />
<input class="button" type="radio" name="toggle" id="two" />
<input class="button" type="radio" name="toggle" id="three" />
</div>
</body>
<script src="script.js"></script>
</html>
In the above file, all we did was to create a div container to hold three input tags of type radio which all have the same name attribute.
The next thing we need to do is create a style.css file with the following styles:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
input {
height: 30px;
width: 30px;
appearance: none;
background-color: black;
border-radius: 50%;
opacity: 0;
}
input:hover {
cursor: pointer;
}
.tri-state-toggle {
display: flex;
justify-content: center;
border: 3px solid black;
border-radius: 50px;
}
#one {
opacity: 1;
}
So in our styles:
- We removed all the default padding and margin that comes with our html page.
- For our body, we set the height and width to be 100% of the viewport height and width respectively. Then we used flexbox to align everything to the center of our screen.
- For our input tag, we first set the height and width of each of our input element to 30px respectively. Then we set appearance to none so we can add our own styling to the radio button by adding a border radius of 50% to make them a circle, an opacity of zero to make them invisible by default and a background-color of black so we can actually see them when we make any of them visible.
- We added cursor: pointer on hover to make it a little more elegant.
- We used flexbox to center our input tags inside of our tri-state-state container, then added a border-radius of 50px to make it look much better.
- Finally we make the first input element visible.
After the css, comes the javascript.. We need to create a script.js file and add the following code:
var buttons = document.getElementsByClassName("button");
var arr = [...buttons];
arr.forEach((element, index) => {
element.addEventListener("click", () => {
element.style.opacity = "1";
arr
.filter(function (item) {
return item != element;
})
.forEach((item) => {
item.style.opacity = "0";
});
});
});
So in our javascript file, this is what we did:
- We grabbed our input elements (radio buttons) using the getElementsByClassName() method.
- And because our buttons variable on line 1 is an htmlCollection, we wouldn’t be able to use the forEach method on it; so we created an array where we can store a non-live version of our htmlCollection using the spread operator.
- So the next thing we did was to add a click event listener to each of our radio button such that the opacity of any button clicked will be changed to “1”. Then we filtered our array (picking out the elements that were not clicked) then setting their opacity to “0”.
And voila! There you have it!! Your three state toggle switch!!!
If you have any suggestions on how to further improve the switch, please let me know.
Now you can go a step further by using this switch to change the background color of your page by making a few adjustments to your javascript code, or you can simply just copy and paste the following code into your javascript file:
var buttons = document.getElementsByClassName("button");
var arr = [...buttons];
arr.forEach((element, index) => {
element.addEventListener("click", () => {
element.style.opacity = "1";
if (index == 0) {
document.getElementsByTagName("body")[0].style.backgroundColor = "white";
} else if (index == 1) {
document.getElementsByTagName("body")[0].style.backgroundColor = "teal";
} else {
document.getElementsByTagName("body")[0].style.backgroundColor =
"rgb(92, 204, 125)";
}
arr
.filter(function (item) {
return item != element;
})
.forEach((item) => {
item.style.opacity = "0";
});
});
});