@madpilot rants

Simulating the iOS “slider” checkbox, using just CSS

… well, some CSS and one image.

I’ve been really interested in emulating the iOS UI in HTML, CSS and JS. Not for any useful reason, more out of morbid curiosity. It could come in handy for home screen web applications, but for standard webapps, I’m beginning to think the uncanny valley plays too big a role to give good results. Regardless, it’s something I’m still playing with.

One of the elements that is quite different between Mobile Safari and native iOS applications is the rendering of checkboxes. Mobile Safari renders them in a similar way to desktop Safari – as a traditional checkbox, but native iOS application render a slider:

Example of the slider in iOS

There have been a number of techniques to simulate this in the browser: the most popular is to replace the checkbox with a couple of spans. The problem with this technique is that, unless you code them in via JavaScript, you lose all of the default events that occur, and even if you do, you are bound to forget one.

By accident, I found that you can clear the default styling of a checkbox using the -webkit-appearance: none CSS rule. Which gives us a completely blank state to work with. So let’s start with what the checkbox looks like without any styling:

The default style for checkboxes in iOS

Next, let’s add  -webkit-appearance: none – you’ll notice the checkbox disappears

iOS checkbox with -webkit-appearance: nonw

Next, we’ll add a background graphic that looks like the slider. This is the one I did. It is terrible, but it’ll do for this example. You’ll notice that it has both the “On” and “Off” sides in one graphic. More on that in a second.

Checkbox sprite

So now we can drop in the CSS to style it:

input[type=checkbox] {
  border: 1px solid #686868;
  height: 27px;
  width: 79px;
  -webkit-appearance: none;
  -webkit-border-radius: 13px;
  background-image: url(/blog/wp-content/uploads/2011/12/checkbox-background.png);
  background-position: -52px 0;
  background-repeat: no-repeat;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-duration: 400ms;
  -webkit-animation-name: checkbox-switch-off;
}

input:checked[type=checkbox] {
  background-position: 0 0;
  -webkit-animation-name: checkbox-switch-on;
}

@-webkit-keyframes checkbox-switch-on {
  from {
    background-position: -52px 0;
  }
  to {
    background-position: 0 0;
  }
}

@-webkit-keyframes checkbox-switch-off {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -52px 0;
  }
}

So what is happening here? It’s pretty straight forward actually. We put a border, and set the height and width appropriately, then set a border radius (we are simulating iOS 5 here, so they are rounded). Next we add our background images, and set the background position so that the “Off” state is showing, using regular old CSS spriting.

Next, we target the checked state, using the :checked pseudo class. This will move the background image to the “On” state when it is checked.

Finally, we add some a slide animation. We create a webkit animation that tweens the background image from one position to the other. Simple really!

Demo

The final style

Problems

  1. It’s  webkit only at the moment. If you can zero out checkbox styling on Firefox or Opera, it wouldn’t be difficult to implement for them too (Just change the vendor specific CSS and animations). It might also work in IE 10?
  2. The animation will always go from On to Off on page load, because the CSS animation will run. You could easily fix this with a line of JavaScript, but if anyone else can suggest a way to do it purely in CSS, I’d be all ears.

Leave a comment