DEV Community

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

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

devggaurav profile image Gaurav Updated on ・2 min read

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 😀

Discussion (23)

pic
Editor guide
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 Author

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 Author

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 Author

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 Author

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 Author

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

Collapse
mjprogramation 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 Author

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 Author • 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 Author

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
Nikhil M Warrier

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 Author

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 Author

Nice😀

Collapse
maihar91 profile image
maihar91

Nice one!

Collapse
devggaurav profile image
Gaurav Author

Thank u!