DEV Community

Cover image for Let's create a custom toggle switch using HTML and CSS.
Gaurav
Gaurav

Posted on • Updated on

Let's create a custom toggle switch using HTML and CSS.

Hello everyone! In this quick tutorial, let's learn how to create a custom toggle switch using HTML and CSS.

Step 1 - The HTML.

<label class="switch">
     <input type="checkbox" class="checkbox">
     <span class="toggle-thumb">

          <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" style="fill:#4ADE80;transform:;-ms-filter:"><path d="M10 15.586L6.707 12.293 5.293 13.707 10 18.414 19.707 8.707 18.293 7.293z"></path></svg>

          <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" style="fill:#F87171;transform:;-ms-filter:"><path d="M16.192 6.344L11.949 10.586 7.707 6.344 6.293 7.758 10.535 12 6.293 16.242 7.707 17.656 11.949 13.414 16.192 17.656 17.606 16.242 13.364 12 17.606 7.758z"></path></svg>

     </span>
</label>
Enter fullscreen mode Exit fullscreen mode

Here, the label with the class 'switch' is like the main container of our switch. The span with the class of 'toggle-thumb' is the circle part of the switch and inside this span are the 2 SVG icons that we are going to use. And We will use the checkbox to toggle the switch.

Step 2 - Basic Styles

.switch {
      display: inline-block;
      width: 60px;
      height: 34px;
      position: relative;
    }

.toggle-thumb {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: #475569;
      border-radius: 40px;
      cursor: pointer;
    }
Enter fullscreen mode Exit fullscreen mode

After these styles, the switch should look like this

Alt Text

Step 3 - Creating the toggle thumb and hiding the checkbox.

For creating the toggle thumb we need to add the '::before' pseudo-element to the 'toggle-thumb'.

 .toggle-thumb:before {
      content: "";
      height: 26px;
      width: 26px;
      position: absolute;
      left: 4px;
      bottom: 4px;
      border-radius: 50%;
      background-color: #E2E8F0;
      transition: .4s all ease;
    }
Enter fullscreen mode Exit fullscreen mode

And to hide the checkbox

.checkbox {
      opacity: 0;
      width: 0;
      height: 0;
    }
Enter fullscreen mode Exit fullscreen mode

It should look like this now,
Alt Text

Step 4 - Adding the functionality.

To add the functionality to our switch we need to add transform to our 'toggle-thumb::before' when our checkbox is checked. So to do that,

.checkbox:checked + .toggle-thumb:before {
      transform: translateX(26px);
    }
Enter fullscreen mode Exit fullscreen mode

That's it. Here is the demo of the switch.
Alt Text

Thanks 😀

Top comments (23)

Collapse
 
mborgeaud profile image
Matias Borgeaud

Great tip!
I just did a small change to the CSS to give a transition effect to both the tick and the cross.

knot

.toggle-thumb {
 ...
 overflow: hidden;
}
svg:nth-child(1) {
  position: relative;
  left: -26px;    
}
svg {
  transition: .4s all ease;
}
.checkbox:checked + .toggle-thumb > svg {
  transform: translateX(26px);
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
devggaurav profile image
Gaurav

Hey! This looks amazing😍🤩 Thank u so much!

Collapse
 
billerr profile image
Bill Gouveros

Nice quick tut! Since it's aimed to beginners, it would also benefit from a quick explanation of why clicking the also influences the invisible checkbox.

Collapse
 
devggaurav profile image
Gaurav

Oh yea I actually forgot to add that 😅 Thanks for the suggestion

Collapse
 
francisprovost profile image
Francis Provost

Really nice! I love that you used :checked instead of using some JS.

Don't forget to make it accessible to screen readers.
For that I would replace the label by a span. The input would be labelled somewhere else in the form. I would add aria-hidden on the span. That way screen readers will ignore the svgs that are not important for to understand the input.

Collapse
 
devggaurav profile image
Gaurav

Hey, thanks! I will surely make these changes.😄

Collapse
 
csorbamatyi profile image
Matyi Csorba

Cool example. I love these pure css solutions.
Here's mine
codepen.io/Tyutyesz/pen/VwvNbbZ

Collapse
 
devggaurav profile image
Gaurav

Looks nice. clean and minimal

Collapse
 
b_e_sandbakk profile image
Bjørn Erik Sandbakk

Thanks for a great example. A question, can this be done with radio as well? I see a great benefit in some radio choice lists using this technic.

Greatings from Norway.

Collapse
 
devggaurav profile image
Gaurav

Hey, thanks! Yes, I think we can also create a custom radio button. I've never tried it but I will try😀

Collapse
 
butalin profile image
Anass Boutaline

Great article, i never tried to use css do that, alwayse use js to trigger an event, but css seems to be more accurate, thanks

Collapse
 
devggaurav profile image
Gaurav

Thanks!

Collapse
 
shtep profile image
jim shtepa

I am wondering if you could suggest basic integration to, for example, switching themes? What would be the best approach?

Collapse
 
devggaurav profile image
Gaurav • Edited

Yes, we can use this toggle to switch themes using javascript. We will have to add an event listener on the checkbox to listen for the 'change' event and create a function that toggles the theme on the body. First, you have to define your dark-mode class in your CSS and the javascript will look something like this,

const checkBox = document.getElementsByClassName("checkbox");
const body = document.body;

checkbox.addEventListener("change", darkMode);

function darkMode() {
      body.classList.toggle("dark-mode")
}

Enter fullscreen mode Exit fullscreen mode
Collapse
 
shtep profile image
jim shtepa

Is there any reason not using .checkbox {display:none} instead of .checkbox {
opacity: 0;
width: 0;
height: 0;
}?

great material and presentation. thank you!

Collapse
 
devggaurav profile image
Gaurav

Hey, thank u so much for pointing that out. It's actually my fault😅 I was trying different things to hide that checkbox to see what works best (like display: none, height:0 width:0, opacity:0, etc), and by mistake, I forgot to remove the extra code when writing this article😅display: none also works!.

Collapse
 
nikhilmwarrier profile image
nikhilmwarrier

Awesome! I made one, but without svg...
Now I will try this too!!!

Collapse
 
deepakpal profile image
Deepak Pal

Nice one like it

Collapse
 
devggaurav profile image
Gaurav

Thank u!

Collapse
 
konrud profile image
Konstantin Rouda

Good article, nicely done. I remember I've done something similar and even tried to make a web component from it.
I've called it switch-web-component

Collapse
 
devggaurav profile image
Gaurav

Nice😀

Some comments may only be visible to logged-in visitors. Sign in to view all comments.