Site icon Sir Codex

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/

Exit mobile version