How to create a three state toggle switch using html, css and javascript
Tags: javascript, beginners, webdev, programming
Published: 2022-03-09 23:18:07

Naturally, everything has two sides: we have day and night, sun and moon, light and darkness, on and off and so on.. and if there is anything I've learned about humans, is that we love going against nature. 

Humanity have looked for a way to partially render our legs useless by creating vehicles for transportation and also partially eliminated darkness at night by creating light bulbs and switches. 

Speaking of switches, we're going to manipulate the natural order of a toggle switch in this tutorial using html css and javascript.

Naturally, a toggle switch is meant to only have two states hence the name "toggle". But we are humans and we love to change things, so let me show you how to change that now.

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.

So firstly, we need to create an index.html file with the following content:

``` html
<!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:

``` css
* {
  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:**
1. We removed all the default padding and margin that comes with our html page.
2. 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.
3. 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.
4. We added cursor: pointer on hover to make it a little more elegant.
5. 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.
6. 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:

``` javascript
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:**
1. We grabbed our input elements (radio buttons) using the _getElementsByClassName()_ method.
2. And because our buttons variable on line 1 is an [htmlCollection](https://webcodespace.com/htmlcollection-vs-nodelist-in-javascript) , 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.
3. 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!!!

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 script.js file:

``` javascript
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";
      });
  });
});
```