Even Better CSS3 Toggle Switches!
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.
Source Link: http://www.sitepoint.com/better-css3-toggle-switches/