DEV Community

Gulshan
Gulshan

Posted on

Accessibility of Toggle Buttons

Quick Summary

A task of making a cool toggle button comes your way and you’re headed down the div lane. What happens next? Sounds like a crime thriller but it could actually be a nightmare for your users. Explore what is the best approach, how to ensure the button is accessible, and what could go wrong when you replace native HTML elements with artificial ones.

Toggle Button

To begin making a toggle button or an icon button with toggle feature, the easiest and straight forward option is to use a div and style it according to the design. Like this button here

We have a like button with a thumbs-up icon similar to what we see under social media posts, clicking it makes it active and clicking it again makes it inactive or reset. Works well visually and functionally. But right now, it has a few things missing.

Trap of Artificial Button

Since we used a div and icon to make a toggle button, it does not have the properties of a native HTML button. Which means we would miss out on these built-in features

Feature Div Button Comment
Tab indexing Using keyboard to navigate
Button label Users have to guess the usage by icon
Keyboard support Spacebar support
Default focus styles
Semantic Browser doesn’t know if it is a button
Accessibility ⚠️ Button is inherently more accessible but not totally
Form features

These issues could affect the user experience and they are easily be overlook if not tested specifically. Even if we notice and try to fix them, we would need to manually solve them.

Addressing Accessibility

How do we solve the issues discussed above?

Well, the best solution would be to use a <button> element. Using button in place of the div will restore the built-in button features. This could affect the styles of the icon button due to the default button styles. All browser default button styles can be removed by using a CSS property all: unset, but this property removes every default style, including the focus styles which we should still keep. Alternatively we can only update the styles that are affecting our button design, such as background, margin and border.

Using a button, improves the element without any extra work. However, there are still a few more things to address

  1. It is still a generic button element and not a toggle button

  2. It still misses the label

  3. ARIA tags for A11y

  4. Toggle state

Using Labels to Clearly Describe the Button

The purpose of a button must be clear to the user. An icon on its own may not be clear enough or even accessible. Icons are graphics made of lines and shapes, and their interpretation can be highly subjective. They also limit users to understanding the control only visually.

Adding a descriptive label to the button improves accessibility, while showing the label on hover can enhance the overall user experience.

Here’s a list of things to consider for button labelling

  1. Visible text label next to the icon - Ideally, just include a label if there’s no good reason to hide it

  2. Hidden text in the button - Add the text in a span beside the icon and hide it using CSS

  3. Using aria-label - Use the aria-label tag on the button to add a descriptive label

  4. Tooltip on hover - Use a tooltip to show the label when the user interacts with the button

Toggle State

Now we have the button more accessible and working fine. But what about the toggle state? Is it accessible to every user yet? Maybe we can see it visually as the design and styles change after it is clicked and we have the state in our JS probably. But how does the browser know in which state the button is currently? So how would users with assistive tech know the state?

This is where the aria-pressed tag comes in to help. It is meant for using as a state indicator for toggle buttons. We can set the current toggle state of the button in this tag like this

<button aria-pressed="true">...</button>
Enter fullscreen mode Exit fullscreen mode

💡Pro-tip: Do not confuse the user by changing the content of the button when toggled. Also mentioned in MDN docs here

Downsides of Not Using Native Button

Replacing any native HTML element comes with its downsides. Native elements are recognised by the browsers and include a lot of important properties that help with a consistent cross-browser behaviour and accessibility.

Although we don’t have a dedicated toggle button in HTML but by using a generic button element with proper labels and pressed state, we can get close to the best possible solution.

TL;DR

A quick checklist for toggle/icon buttons

  1. Basic button features (by browser)

  2. Descriptive button label

  3. Accessibility tags

  4. Toggle state

Links to resources

Top comments (0)