3 State Switches are not tough - Ultimate guide to CSS Switches using CSS only

navdeepm20

Navdeep Mishra

Posted on September 20, 2023

3 State Switches are not tough - Ultimate guide to CSS Switches using CSS only

Hi there, when it comes to switches most people look for modern libraries but building core is very important.
Creating switches are very easy. Today I will be sharing the guide to create CSS switches.

We'll be seeing -

  1. 2 state switches
  2. 2 state switches with custom icons.
  3. 3 state switches

2 State Switches

For creating switches you need a way to figure out the active states. If you are using JavaScript then there are lot of ways you can do it by dynamically adding classes on click. When it comes to css we have one very popular way which is by using the input type checkbox. Which changes it's state and you can target that state easily with CSS only.

Check the below html structure -



<div class="switch1-container">
      <h5> Simple two state switch</h5>
      <div class="switch1">
        <input type="checkbox" id="switch1-input"/>
        <label for="switch1-input"></label>
        <span class="switch-bg"></switch>
      </div>
</div>


Enter fullscreen mode Exit fullscreen mode

Note - Here in this html structure for giving the bg to the switch I experimented with a separate span and used absolute positioning. You can achieve the similar behavior using the ::before pseudo element.

Main thing to know here is that for getting the on status for the switch we can use the checked state of the input element.
You can easily get it on input using :checked pseudo class.

For styling the CSS switch button we have to make use of the input label. The good thing is when you click on the label then input states gets toggled. So hide the input and design the label with good looking round circle.

Once you designed the b and the circle now for moving the circle with the bg to give feel like a switch. Make use of transform property. Use translateX to move the circle and add transition on transform to make it smooth. 🙃

That's it
Your switch is ready. 🫡

Checkout the Css below to understand what we discussed.
Practical knowledge is more important you know.😎



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

:root{
    --clr-primary: #d9d9d9;
  --clr-secondary:#fafafa;
  --clr-clear:#ffffff;
  --clr-grey: #6d6d6d;
  --clr-dark:#1e1e1e;
  --ff-base:'Inter', sans-serif;
  --fw-regular: 400;
  --fs-200:0.875rem;
  --fs-300:1rem;
  --fs-400:1.125rem;
  --fs-500:1.375rem;
  --fs-600:1.75rem;
  --fs-700:3.25rem;

}
html{
  color-scheme: dark;
}
body{
  font-family: var(--ff-base);
  font-size: var(--fs-300);
  font-weight: var(--fw-regular);
}

.container{
  max-width:80%;
  margin: auto;
  height:100dvh;
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
/*   justify-content:center; */
  padding: 4rem;
}

input{
  display:none;
  cursor: pointer;
}
label{
  cursor: pointer;
}

.switch1-container h5{
  margin-bottom: 1rem;
}
.switch1{
  position:relative;
  border-radius: 30px;
  width:6rem;
  height:2.5rem;
  background: #ccc;
  display:flex;
  align-items:center;
  transition: .3s background-color ease;
}
.switch-bg{
  background-color: #eceeef;
  position:absolute;
  top:4px;
  left:5px;
  width:90%;
  height:80%;
  border-radius:30px;
  transition: background-color .2s ease-out;
}


.switch1 label {
  background-color:white;
  border: 1px solid #bbb;
  display:inline-block;
  width:24px;
  height:24px;
  border-radius:50%;
  display:inline-block;
  vertical-align:bottom;
  margin:5px 8px;
  z-index:2;
  transition: transform .3s ease;

}
.switch1 input:checked + label{
  transform: translateX(56px);
}
.switch1 input:checked + label + .switch-bg {
  background-color: dodgerblue;
}



Enter fullscreen mode Exit fullscreen mode

2 State Switches with Custom Icon
For adding the icon to your switches is very easy you can use various way of doing that. I picked it using css only even no extra Html. I used fontawesome for directly using icons in the stylesheet. The one I created is useful when you want to toggle between dark and night mode. 😎

Just add this to your styles sheet and in Html file.

Html



<div class="switch2-container">
      <h5> Simple two state siwtch with custom icon</h5>
      <div class="switch2">
        <input type="checkbox" id="switch2-input"/>
        <label for="switch2-input"></label>
        <span class="switch-bg"></switch>
      </div>
    </div>


Enter fullscreen mode Exit fullscreen mode

Css




.switch2-container h5{
  margin-bottom: 1rem;
}
.switch2{
  position:relative;
  border-radius: 30px;
  width:6rem;
  height:2.5rem;
  background: #ccc;
  display:flex;
  align-items:center;
  transition: .3s background-color ease;
}
.switch2-bg{
  background-color: #eceeef;
  position:absolute;
  top:4px;
  left:5px;
  width:90%;
  height:80%;
  border-radius:30px;
  transition: background-color .2s ease-out;
}


.switch2 label {
/*   background-color:white; */
/*   border: 1px solid #bbb; */
  display:inline-block;
  width:24px;
  height:24px;
  border-radius:50%;
  display:inline-block;
  vertical-align:bottom;
  margin:3px 8px 0px;
  z-index:2;
  transition: transform .3s ease;

}
.switch2 input:checked + label{
  transform: translateX(56px);
}
.switch2 input:checked + label + .switch-bg {
  background-color: dodgerblue;
}

.switch2 label::before{
  font: var(--fa-font-solid);
  content: "\f185";
  color: gold;
  font-size: 1rem;
  border: 1px solid #ccc;
  border-radius: 50%;
  padding: 4px;
}
.switch2 input:checked + label::before{
  content: "\f186";
  color:gold;
  border: none;
}
.switch2 input:checked + label + .switch-bg{
  background: black;
}


Enter fullscreen mode Exit fullscreen mode

Now the third one is the powerful one.
3 State Switches

The godfather

For this one I use input type radios because of one good behavior that when you have radio group and each has same name attribute then if you select one then the other one will be de-selected automatically.

I created my html structure like this.



 <div class="switch3-container">
      <h5> Simple three state siwtch</h5>
      <div class="switch3">
        <input type="radio" id="switch3-radio1" name="radio"/>
        <label for="switch3-radio1">FrontEnd</label>

        <input type="radio" id="switch3-radio2" name="radio"/>
        <label for="switch3-radio2">BackEnd</label>

        <input type="radio" id="switch3-radio3" name="radio"/>
        <label for="switch3-radio3">FullStack</label>

      </div>
    </div>



Enter fullscreen mode Exit fullscreen mode

For this I have used three html input elements with type radio.
Each has it's own label for showing the text.
For highlighting the selected option, I have use the ::before pseudo element on .switch3.

Thanks to new :has selector of css which made this more easier and cleaner html as well.

Check the css below -



.switch3-container h5{
  margin-bottom: .7rem;
}
.switch3
{

  position: relative;
  height:50px;
  display:flex;
  justify-content:space-around;
}
.switch3 label{
  padding: 1rem;
  z-index:1;
}
.switch3::before{
  content: '';
  position: absolute;
  left:0;
  width: 34%;
  height: 100%;
  background: #14142a;
  border: 1px solid #fff;
  border-radius: 12px;
  opacity: .5;
  transition: .5s left ease;
}

.switch3:has(#switch3-radio1:checked)::before{
  left: 0%;
}
.switch3:has(#switch3-radio2:checked)::before{
  left: 33%;
}
.switch3:has(#switch3-radio3:checked)::before{
  left: 66%;
}


Enter fullscreen mode Exit fullscreen mode

That's how all three looks like.

Toggle switches using css only with three state switch

Experiment with my codepen - Codepen Live

Similarly we can create 4 state switch as well.
If you have any doubts or questions, feel free to discuss in the comments.
Any better approach? let's discuss. 😎

Thanks for reading.
Please follow for more Webdev content. 😉

Navdeep M.

💖 💪 🙅 🚩
navdeepm20
Navdeep Mishra

Posted on September 20, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related