How to create a three state toggle switch using HTML, CSS and JavaScript

In this tutorial, I am going to be showing you how to build a toggle switch with three states.

Normally a toggle switch has just two states - ON and OFF. That’s why it’s called a toggle switch. But I was on the Frontend Mentor website the other day, scouring through for some frontend dev challenges to work on while I came across the calculator challenge on their website.

Working on this challenge required building a toggle switch with three states. The purpose of this switch is to enable users switch between the three themes of the calculator. While working on this challenge, I found that building out the toggle switch was a little challenging. So I decided that when I figure out how to build this toggle switch, I will create a tutorial explaining how I did it, because I believe there might be others who could benefit from it.

Prerequisites

I will try to explain everything as best as I can. However, having a good understanding of HTML, CSS, and JavaScript will help you go through this tutorial effortlessly.

This is what we are going to be building:

Alt Text

Let’s begin building!

Create the HTML file

To begin, create the HTML boilerplate with a div in the body tag to hold three radio buttons.

<!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>

From the above HTML code, you can see we have a div with a class name of tri-state-toggle, and we’ve also linked to our JavaScript and CSS file.

Style the HTML

If you take a look at our HTML code in the browser right now, you’ll notice that everything looks ugly. To improve the appearance, we need to add some styles.

The goal of applying these styles to the HTML is to:

  • Place the switch at the center of the page.
  • Hide two out of the three radio buttons from the switch.

With these goals in mind, feel free to apply whatever style you like to your HTML.

To begin styling, the first thing you need to do in the CSS file, is to remove all the browser-default styles (the default padding and margin that comes with the HTML page) to ensure that the styling is consistent.

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

Then, center the switch in the body of the page using flexbox.

body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

Concerning the radio buttons, set the height and width of each button to 30px and add a border radius of 50% to make it circular. Then, set the appearance to none, so you can be able to override the default styling. Finally add cursor: pointer to the styles to change the cursor on hover.

input {
  height: 30px;
  width: 30px;
  appearance: none;
  background-color: black;
  border-radius: 50%;
  cursor: pointer;
}

The next thing to do now, is to style the tri-state-toggle container using flexbox:

.tri-state-toggle {
  display: flex;
  justify-content: center;
  border: 3px solid black;
  border-radius: 50px;
}

Also, add a border and give it a border radius of 50px to make it circular.

Now that we have everything set, we need to make only the first radio button visible and hide the rest of the buttons.

To achieve this, we need to update the style for the radio button by adding opacity: 0 to it.

input {
  height: 30px;
  width: 30px;
  appearance: none;
  background-color: black;
  border-radius: 50%;
  cursor: pointer;
  opacity: 0;
}

The finally, we’d make the first radio button visible by adding the following:

#one {
  opacity: 1;
}

Complete CSS Code

With everything done, this is how the CSS file would look:

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
input {
  height: 30px;
  width: 30px;
  appearance: none;
  background-color: black;
  border-radius: 50%;
  cursor: pointer;
  opacity: 0;
  cursor: pointer;
}
.tri-state-toggle {
  display: flex;
  justify-content: center;
  border: 3px solid black;
  border-radius: 50px;
}
#one {
  opacity: 1;
}

Add the JavaScript

To begin the JavaScript, we need to query the radio buttons on the HTML page using the getElementsByClassName method:

var buttons = document.getElementsByClassName("button");
var arr = [...buttons];

Notice that we made use of the spread operator to create the arr variable for the buttons. This is because buttons is an HTMLCollection and the forEach method doesn’t work directly on HTMLCollections. We could have also made use of the for...of statement, but I can’t think of an easy way to get the indexes of the elements using this method.

Next, we would add a click event listener to all the buttons and make it so that whichever button you click will become visible while the rest disappear.

arr.forEach((element, index) => {
  element.addEventListener("click", () => {
    element.style.opacity = "1";

    arr
      .filter(function (item) {
        return item != element;
      })
      .forEach((item) => {
        item.style.opacity = "0";
      });
  });
});

In the above code, after setting the opacity of the clicked button to ‘1’, we go through the array of buttons again to find the remaining buttons (unclicked buttons) by using the filter method, and setting their opacities to “0”.

Complete JavaScript Code

Now you can go a step further by using this switch to change the background color of the page by making a few adjustments to the 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";
      });
  });
});

And voila! There you have it. A three state toggle switch! You can play around the code to understand it better.

three state toggle switch


Written By

Jima Victor

Code lover, crafting cool stuff with code. Also, geeking out in articles for the tech community. 🚀