OB电竞选手

About The Author

Heydon Pickering ( @heydonworks ) has worked with The Paciello Group, The BBC, Smashing Magazine, and Bulb Energy as a designer, engineer, writer, editor, and … More about Heydon ↬

Email Newsletter

Weekly tips on front-end & UX .
Trusted by 200,000+ folks.

Toggle buttons are one of the simpler design patterns out there, often based on just one element. But it’s still easy to design them badly. Making them inclusive is a question of language, visual design, markup, and behavior.

In this inaugural post, I’ll be exploring what it takes to make toggle buttons inclusive. As with any component, there’s no one way to go about this, especially when such controls are examined under different contexts. However, there’s certainly plenty to forget to do or to otherwise screw up, so let’s try to avoid any of that.

Improving Interface Design

Did you know that with just a few simple tricks, you can help make a user’s interaction more pleasant? We've got your back, with an inspiring list of dialog and modal windows, signup and login screens, navigation and menus, and even more sliders and toggles. Read a related article →

Changing State

If a web application did not change according to the instructions of its user, the resulting experience would be altogether unsatisfactory. Nevertheless, the luxury of being able to make web documents augment themselves instantaneously, without recourse to a page refresh, has not always been present.

More after jump! Continue reading below ↓

Unfortunately, somewhere along the way we decided that accessible web pages were only those where very little happened — static documents, designed purely to be read. Accordingly, we made little effort to make the richer, stateful experiences of web applications inclusive.

A popular misconception has been that screen readers don’t understand JavaScript. Not only is this entirely untrue — all major screen readers react to changes in the DOM as they occur — but basic state changes, communicated both visually and to assistive technology software, do not necessarily depend on JavaScript to take place anyway.

Checkboxes And Radio Buttons

Form elements are the primitives of interactive web pages and, where we’re not employing them directly, we should be paying close attention to how they behave. Their handling of state changes have established usability conventions we would be foolish to ignore.

Arguably, an out-of-the-box input of the checkbox type is a perfectly serviceable on/off switch all its own. Where labelled correctly, it has all the fundamental ingredients of an accessible control: it’s screen reader and keyboard accessible between platforms and devices, and it communicates its change of state ( checked to unchecked or vice versa) without needing to rebuild the entire document.

In the following example, a checkbox serves as the toggle for an email notifications setting.

								
								
								
							
						
The notify my email control with checkbox checked

Screen reader software is fairly uniform in its interpretation of this control. On focusing the control (moving to it using the Tab key) something similar to, “Notify by email, checkbox, unchecked” will be announced. That’s the label, role, and state information all present.

On checking the checkbox, most screen reader software will announce the changed state, “checked” (sometimes repeating the label and role information too), immediately. Without JavaScript, we’ve handled state and screen reader software is able to feed back to the user.

Screen readers are not just for the blind

Some operate screen readers to assist their understanding of an interface. Others may be visually dyslexic or have low literacy. There are even those who have little physical or cognitive trouble understanding an interface who simply prefer to have it read out to them sometimes.

Supporting screen reader software is supporting screen reader software, not blind people . Screen readers are a tool a lot of different people like to use.

In this case, the on/off part of the switch is not communicated by the label but the state. Instead, the label is for identifying the thing that we are turning off or on. Should research show that users benefit from a more explicit on/off metaphor, a radio button group can be employed.

						
						
Notify by email
Fieldset with notify by email group label (legend) and radio buttons labeled on and off. The on one is selected.

Group labels are a powerful tool. As their name suggests, they can provide a single label to related (grouped) items. In this case, the

group element works together with the element to provide the group label “Notify by email” to the pair of radio buttons. These buttons are made a pair by sharing a name attribute value, which makes it possible to toggle between them using your arrow keys. HTML semantics don’t just add information but also affect behavior.

In the Windows screen readers JAWS and NVDA, when the user focuses the first control, the group label is prepended to that control’s individual label and the grouped radio buttons are enumerated. In NVDA, the term “grouping” is appended to make things more explicit. In the above example, focusing the first (checked by default) radio button elicits, “Notify by email, grouping, on radio button, checked, one of two” .

Now, even though the checked state (announced as “selected” in some screen readers) is still being toggled, what we’re really allowing the user to do it switch between “on” and “off”. Those are the two possible lexical states , if you will, for the composite control.

Styling form elements

Form elements are notoriously hard to style, but there are well-supported CSS techniques for styling radio and checkbox controls, as I wrote in Replacing Radio Buttons Without Replacing Radio Buttons . For tips on how to style select elements and file inputs, consult WTF Forms? by Mark Otto.

This doesn’t quite feel right

Both the checkbox and radio button implementations are tenable as on/off controls. They are, after all, accessible by mouse, touch, keyboard, and assistive technology software across different devices, browsers, and operating systems.

But accessibility is only a part of inclusive design. These controls also have to make sense to users; they have to play an unambiguous role within the interface.

The trouble with using form elements is their longstanding association with the collection of data. That is, checkboxes and radio buttons are established as controls for designating values . When a user checks a checkbox, they may just be switching a state, but they may suspect they are also choosing a value for submission.

Whether you’re a sighted user looking at a checkbox, a screen reader user listening to its identity being announced, or both, its etymology is problematic. We expect toggle buttons to be buttons, but checkboxes and radio buttons are really inputs.

A True Toggle Button

Sometimes we use

But these are only one variety of button, covering one use case. In truth,

The generic button is your go-to element for changing anything within the interface (using JavaScript and without reloading the page) except one’s location within and between documents, which is the purview of links.

Next to links, buttons should be the interactive element you use most prolifically in web applications. They come prepackaged with the “button” role and are keyboard and screen reader accessible by default. Unlike some form elements, they are also trivial to style.

So how do we make a

WAI-ARIA state attributes like aria-pressed behave like booleans but, unlike standard HTML state attributes like checked they must have an explicit value of true or false . Just adding aria-pressed is not reliable. Also, the absence of the attribute would mean the unpressed state would not be communicated (a button without the attribute is just a generic button).

You can use this control inside a form, or outside, depending on your needs. But if you do use it inside a form, the type="button" part is important. If it’s not there, some browsers will default to an implicit type="submit" and try to submit the form. You don’t have to use event.preventDefault() on type="button" controls to suppress form submission.

Switching the state from true (on) to false (off) can be done via a simple click handler. Since we are using a <-- Playing state -->

Because aria-label overrides the unicode symbol text node, the paused button is announced as something similar to, “Play button, not pressed” and the playing button as , “Play button, pressed” .

This works pretty well, except for where voice recognition and activation is concerned. In voice recognition software, you typically need to identify buttons by vocalizing their labels. And if a user sees a pause symbol, their first inclination is to say “pause”, not “play”. For this reason, switching the label rather than the state is more robust here.

Three implementation examples. The first just changes label from play to pause and is okay. The second keeps the play label and changes state, which is incorrect because the pause button cannot be identified with voice recognition. The third changes label and state so the button becomes a pause button which is pressed, which is incorrect. Only use one of the first two implementations.
Never change label and state at the same time. In this example, that would result in a paused button in the pressed state. Since the video or audio would be playing at this point, the lexical "pause" state cannot be also be considered "pressed" on "on".

Auxiliary labeling

In some circumstances, we may want to provide on/off switches which actually read “on/off”. The trick with these is making sure there is a clear association between each toggle switch and a respective, auxiliary label.

Imagine the email notification setting is grouped alongside other similar settings in a list. Each list item contains a description of the setting followed by an on/off switch. The on/off switch uses the terms “on” and “off” as part of its design. Some elements are provided for styling.

	
	

Notifications

  • Notify by email
  • Notify by SMS
  • Notify by fax
  • Notify by smoke signal
A list of notifications settings with associated buttons reading with either on or off highlighted, depending on the state

The virtue of lists is that, both visually and non-visually, they group items together, showing they are related. Not only does this help comprehension, but lists also provide navigational shortcuts in some screen readers. For example, JAWS provides the L (list) and I (list item) quick keys for moving between and through lists.

Each ‘label’ and button is associated by belonging to a common list item. However, not providing an explicit, unique label is dangerous territory — especially where voice recognition is concerned. Using aria-labelledby , we can associate each button with the list’s text:

	
	

Notifications

  • Notify by email
  • Notify by SMS
  • Notify by fax
  • Notify by smoke signal

Each aria-labelledby value matches the appropriate span id , forming the association and giving the button its unique label. It works much like a element’s for attribute identifying a field’s id .

The switch role

Importantly, the ARIA label overrides each button’s textual content, meaning we can once again employ aria-pressed to communicate state. However, since these buttons are explicitly “on/off” switches, we can instead use the WAI-ARIA switch role , which communicates state via aria-checked .

	
	

Notifications

  • Notify by email
  • Notify by SMS
  • Notify by fax
  • Notify by smoke signal

How you would style the active state is quite up to you, but I’d personally save on writing class attributes to the s with JavaScript. Instead, I’d write some CSS using pseudo classes to target the relevant span dependent on the state.

	
	[role="switch"][aria-checked="true"] :first-child, [role="switch"][aria-checked="false"] :last-child { background: #000; color: #fff; }

Traversing the settings

Now let’s talk about navigating through this settings section using two different strategies: by Tab key (jumping between focusable elements only) and browsing by screen reader (moving through each element).

Even when navigating by Tab key, it’s not only the identity and state of the interactive elements you are focusing that will be announced in screen readers. For example, when you focus the first