Skip to main content
Easy, All CSS custom HTML checkboxes
General

Easy, All CSS custom HTML checkboxes

Apr 17, 2014 by Mobomo

orange
Let's face it, nobody likes a plain ol' checkbox and sometimes (depending on what you're trying to accomplish), they can be tricky to style without dropping in a javascript library. Recently, while developing our new app Smashbook, I needed to replicate the native iOS style toggle switch. Attempting to replicate by using only HTML and CSS, here's what I came up with...

We'll start with the HTML.

<div class="setting">
  Off/On
  <input type="checkbox">
  <div class="track"></div>
  <div class="toggle"></div>
</div>

Pretty simple, right? Now for the CSS. This is the container for our toggle.

.setting {
  position: relative;
  width: 200px;
  padding: 12px;
  border: 1px solid #9c9691;
  border-radius: 4px;
}

The only thing important here is the position: relative declaration. This allow us to absolutely position the elements contained inside it. The rest is completely arbitrary. Next, comes the toggle switch and track it will slide along.

.track {
  position: absolute;
  right: 12px;
  bottom: 6px;
  width:50px;
  height: 29px;
  background: #9C9691;
  border-radius: 15px;
  box-shadow: inset 0 1px 3px #797470;
}

And for the toggle:

.toggle {
  position: absolute;
  top: 8px;
  right: 34px;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  border: 1px solid #8B8580;
  background: #e1dcd7;
}

Not too shabby! Now, just hide that pesky input and give it the same dimensions as the track, opacity: 0 and position it directly on top of the toggle and track. Note: the z-index of 2 ensures input is still clickable.

input[type="checkbox"] {
  position: absolute;
  top: 8px;
  right:12px;
  width:50px;
  height: 29px;
  opacity: 0;
  z-index: 2;
}

Now, add the “clicked” state. Here the track will become green and the + will allow us to target the sibling directly succeeding the input.

input[type="checkbox"]:checked + .track {
  background: #a5cf42;
}

The toggle will then move to the left side of the track. The ~ is the general sibling selector; this let's us target any sibling element succeeding the input.

input[type="checkbox"]:checked ~ .toggle {
  right: 13px;
}

Finally, add a transition to the track and toggle. This will give the toggle slide and the "track changing color" a more natural feel. Tada! There you have it.

.track, .toggle {
  -webkit-transition: all, 0.2s;
  -moz-transition: all, 0.2s;
  -ms-transition: all, 0.2s;
  -o-transition: all, 0.2s;
  transition: all, 0.2s;
}

We implemented this for our upcoming product "Smashbook – Manage Your Tennis Data Like a Pro!"

Also, here's a link to Codepen.io, if you'd like to see a demo https://codepen.io/bryancunningham/pen/oNbmvX


Got any questions? Keep the conversation going! We'd love to hear from you.