45
Accessible custom radio buttons and checkboxes

Accessible custom radio buttons and checkboxes

Embed Size (px)

Citation preview

Accessiblecustom radio buttons

and checkboxes

The pain

Web designers and developers have always struggled with how to customise radio buttons and

checkboxes.

Diagram: A series of differently styled on/off switches.

The main issue is that these elements are notoriously hard

to style - especially across multiple browsers and devices.

In the past, some developers resorted to JavaScript-based solutions to solve this problem.

In some cases this involved using JS to remove the

original radio or checkbox element making the end result inaccessible for a wide range of

assistive technologies.

It can be done

However, it is possible to style these elements without having to use JavaScript. And more importantly, we can make the

end result accessible.

Let’s take a simple example of an on/off switch that can be

applied to either radio or checkbox elements:

unchecked

checked

Diagram: Shows the unchecked and checked version of the switch.

The solution I’m about to demo, has four key accessibility

features:

Feature 1: Using the intended semantic elements, the input and label

elements will be explicitly associated using matching "for"

and "id" values.

Feature 2: The label content can used to describe the purpose of each switch for screen readers. This content is hidden off-screen.

Feature 3: The tick icon makes the two

different states clearly distinguishable - aiding colour-blind users and some types of

cognitive-impaired users.

Feature 4: The switch is keyboard-friendly (operates in the normal way) but we also clearly flag the focus and

hover states.

HTML/CSS

<div class="switch">

<input class="switch__control" type="radio" name="example01" id="example01">

<label class="switch__label" for="example01"> <span class="switch__content">Label content</span> </label>

</div>

Radio

<div class="switch">

<input class="switch__control" type="checkbox" name="example01" id="example01">

<label class="switch__label" for="example01"> <span class="switch__content">Label content</span> </label>

</div>

Checkbox

<div class="switch">

<input class="switch__control" type="checkbox" name="example01" id="example01">

<label class="switch__label" for="example01"> <span class="switch__content">Label content</span> </label>

</div>

ID value

“for” values

/* parent module */.switch { }

/* descendants of parent module */.switch__control { }.switch__label { }.switch__content { }

How does it work?

We can use the parent container to create the overall

dimensions of the switch.

switch

Diagram: Shows the switch layer as a dotted outline.

The control is then positioned on top of the parent, and set with opacity: 0. This means it

exists on the page, and can be interacted with, but it cannot be

seen.

switch

switch__control

Diagram: Shows the control sitting on top of the switch layer.

Then, the label is placed on top of the radio button, and we can

style the background of this label to look like a switch.

switch

switch__control

switch__label

Diagram: Shows label sitting on top of the control.

And finally, the label content is hidden off screen so that it is

available for screen readers, but does not clutter the visual appearance of the switch.

The problem

Checkbox and radio button elements can be manually changed by users - from unchecked to checked etc.

These elements can also be given boolean “checked” and

“disabled” attributes.

<!-- unchecked --><input type="checkbox">

<!-- checked --><input type="checkbox" checked>

<!-- disabled --><input type="checkbox" disabled>

However, for this solution, most of the styling is applied to the label element, rather than the

input.

Unfortunately, the label element has no checked, unchecked or disabled state of its own.

We can get around this using adjacent sibling selectors, which target any label element

that is adjacent to (comes directly after) the input.

/* unchecked input */.switch__control + label { }

/* checked input */.switch__control:checked + label { }

/* diabled input */.switch__control[disabled] + label { }

unchecked

checked

disabled

Diagram: Shows the unchecked, checked and disabled version of the switch.

Different states

Finally, we also want to style the :focus and :hover states of

the switch.

/* unchecked input */.switch__control:hover + label { }.switch__control:focus + label { }

/* checked input */.switch__control:checked:hover + label { }.switch__control:checked:focus + label { }

This gives us a series of possible results that looks like

this:

unchecked hover

unchecked focus

unchecked

checked

checked hover

checked focus

disabledDiagram: Shows variations of the switch.

Demo:

https://russmaxdesign.github.io/switch-checkbox/

Russ Weakley Max Design

Site: maxdesign.com.auTwitter: twitter.com/russmaxdesignSlideshare: slideshare.net/maxdesignLinkedin: linkedin.com/in/russweakley