Mobile support for the CSS toggle switches
Update December 2012
See the latest demos: CSS Toggle Switch.
Update October 2012
After some testing it turns out that the Android 2.3 browser, and possibly other older Webkit browsers, are affected by this older WebKit Adjacent/General Sibling and Pseudo Class Bug, which was causing issues with the toggle switches.
The fix I added is based on the one described in the article above, but applied only to the containers, not the whole
body, for performance reasons.
Another issue was that, on older iOS versions the
inputwas not selected, when tapping the label. The work-around for this was to add an empty
onclickhandler. This handler also makes Opera Mini re-render the page, with the right input selected.
Latest demos: CSS Toggle Switch.
While testing the CSS toggle switches from my last article, I noticed they had issues, or didn’t work at all, in various mobile browsers. The only mobile browsers which seemed to properly support the switches were Firefox Mobile and Opera Mobile.
For both the radio and checkbox-based versions, the switches looked alright but the behavior wasn’t working; the toggle buttons didn’t move when selected.
The only version that worked properly was the one where the checkbox input was placed inside the label.
After some digging, I ended up on The CSS Ninja, who also had similar problems with custom radio and checkbox inputs. His latest solution to the iOS issue was to make sure the input is topmost, and set it’s
opacity to zero.
When applying this technique on the basic checkbox-based example, after taping the switch, the background, border, and text colors where changing, but the position of the button wasn’t.
.toggle input:checked + label:after rule was working, while the
.toggle input:checked ~ span rule, supposed to change the position of the toggle button, wasn’t.
Also, it wasn’t working at all for the radio input-based switch.
After some more digging, it turns out that most mobile Webkits try to prevent reflows, and don’t trigger them when checking/selecting radios or checkboxes. I’m guessing this is mostly for performance reasons.
But, it turns out that setting the
The script I put together is pretty straight forward, except for a couple of things.
I’m using the timeout because there seems to be a delay between taping the label, and the input actually getting checked. If we trigger the reflow too early, before the input is checked, it still won’t change it’s position. So we have to wait until the input is checked, before the reflow.
The reflow is triggered using:
These solutions should also work on other “checkbox-hack” experiments.
The demos are on Github: css-toggle-switch.