Many of you liked my previous article, How to Create a Toggle Switch in CSS3. However, a few issues were raised in the comments and on Twitter…
- How do you apply toggles to radio buttons?
- Can accessibility be improved?
- Why doesn’t it work on older mobile Webkit browsers?
I’ve made some improvements, so please view the demonstration page and the HTML/CSS code…
Radio Button Support
An easy one to start with. Radio buttons function almost identically to checkboxes so we can simply apply a class of “switch” to every input to make it work, e.g.
<div>
<input type="radio" id="radio1" name="radio" class="switch" />
<label for="radio1">first radio button</label>
</div>
<div>
<input type="radio" id="radio2" name="radio" class="switch" checked="checked" />
<label for="radio2">second radio button</label>
</div>
<div>
<input type="radio" id="radio3" name="radio" class="switch" />
<label for="radio3">third radio button</label>
</div>
It’s very satisfying to see two switches alter position at the same time!
Amended Accessibility
Richard from Accessible Web Design raised a couple of concerns. First, the switches change between red and green; if you’re color-blind, it would not be easy to determine whether the switch was on or off. To remedy the problem, I’ve added a check and cross character to the background:
No additional element were required — I simply used a cross character instead of a space and positioned it on the right of the background using text-indent
:
input.switch:empty ~ label:before
{
content: '2718';
text-indent: 2.4em;
color: #900;
}
When the checkbox/radio is checked, it changes to a check character and is moved to the left of the background:
input.switch:checked ~ label:before
{
content: '2714';
text-indent: 0.5em;
color: #6f6;
}
Cross-Browser CSS3 Animation
Originally, I placed the check/cross character on the white switch itself. This is complex for the browser since it must create a transition between two different characters. Firefox worked, but Chrome and IE10 take an easier route: they abandon the animation completely! It appears that Webkit and Trident will not permit animation on a pseudo element if its content is changing — even if you explicitly state that only the margin or color should be animated.
To address the issue, I applied the check/cross to the :before toggle background and removed its transition effect (the color will not smoothly change, but it’s hardly noticeable). Only the white :after switch position is animated now.
The next accessibility issue: keyboard focus. The previous toggles were difficult to use with keyboard only so I’ve applied a different label color and a box shadow to the toggle when it has focus:
input.switch:focus ~ label
{
color: #000;
}
input.switch:focus ~ label:before
{
box-shadow: 0 0 0 3px #999;
}
The result is possibly a little too subtle, but it’s easy to add your own effects:
The focus effect works in Firefox, IE and Opera — but fails in Chrome 26? It looks like a browser bug unless anyone knows differently?
More Webkit Woes
The final problem: the toggle switches fail in mobile browsers using older versions of Webkit such as Safari on the iPad 1.0 and the Android browser. The engine supports labels, is happy with :checkbox selectors and displays the initial state, but doesn’t want to modify pseudo elements after the initial page load. I even broke my own requirements and added a little JavaScript, but the browser laughed at my feeble attempts and wouldn’t budge.
Pseudo element animation has only been added to Webkit recently. It’s frustrating and, unlike the old IE6/7 days, it’s difficult to find workarounds which don’t adversely affect other browsers.
Anyway, assuming legacy Webkit users aren’t part of your demographic, please use the HTML/CSS code however you like. Alternatively, you’ll need to add further (real) elements or JavaScript to make it work.
Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.