David Calhoun’s iPhone slider built with an <input type=”range”> is a fantastic example of what’s possible with a single native input element, combined with pseudo and shadow elements. But, like most things these days, it’s Webkit only.
A recurring comment on HN goes something along the lines of:
Webkit only? Webkit is the new IE6.
But this is quite frankly bullshit. Firefox and Opera still streak ahead in other areas*, but the fact is that Webkit-based browsers consistently implement features we front end devs need on a day-to-day basis. Perhaps that’s a result of Google employing people like Paul Irish as a developer advocate. Perhaps he is responsible for prioritising features that real front ends like us actually want to use? I can only speculate, but the benefits cannot be denied.
So what if you try and build an iOS-inspired toggle switch with a single, native checkbox? Dissecting it mentally, all the pieces seemed to be there. I can use :before and :after pseudo elements to construct the extra visual elements. Maybe I can use data attributes to set the on and off state text? In fact, I even expected Firefox to outshine all other browsers in this test as it would be the only one to animate pseudo elements.
But this is the reality.
Hacks I considered to try and get it working:
- Animating the checkbox element as the toggle handle, along the non animatable pseudo element background.
But this would occur the page to jump around, and is working around the unfortunate ability to animate pseudo elements.
- Hide the native checkbox and use only two pseudo elements for the effect.
This meant no animation. Probably no text. And if animation of pseudo elements eventually drops, it wouldn’t be future proof as it would look a bit naff regardless.
- Use the <label> for the on/off text.
This feels very hacky, and definitely like a compromise. This kind of stuff should ideally be able to plug into any existing solution and work straight away. No modifying of <label>s, just replacement of <input>s. Also, I guess the only way to change the text of the <label> via CSS would maybe be via a :target selector and a content property, which probably wouldn’t work and would require yet more pseudo elements. Slopsville.
But that wasn’t the point of the exercise at all.
Anyhoo, the experiment is designed so that the second Firefox and others begin to implement the missing functionality, it should just work.
* Firefox remains the only browser that can animate pseudo elements, and an Opera nightly is the only browser that currently implements the getUserMedia specification.