Easy, All CSS custom HTML checkboxes

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!” https://twitter.com/tennissmashbook

Also, here’s a link to Codepen.io, if you’d like to see a demo http://codepen.io/bryancunningham/pen/syhvC/
Got any questions? Keep the conversation going! We’d love to hear from you.