Design Accessible Buttons Using Icons

Lindsey Kopacz
InstructorLindsey Kopacz

Share this video with your friends

Send Tweet
Published 2 years ago
Updated a year ago

In this lesson, we are creating the audio player interface more visually appealing using icons from the React Icons library and Font Awesome, in this process, we are also ensuring that the interface remains accessible to screen readers by providing text descriptions for the icons, first by using the title prop on each icon, and then by implementing a visually hidden technique that hides the text descriptions from sighted users but makes them available to screen readers. This involves copying and pasting some CSS code to create a visually-hidden class, adding an aria-hidden attribute to each icon, wrapping each icon in a React fragment, and then adding a span element above each icon with the corresponding text description and the visually-hidden class.

Think about:

  • Why use aria-hidden or visually hide spans?
  • What value does this add to screen reader users?

[0:00] Now that we have the functionality working, let's make this look a little bit more like an audio player. So we're going to change the play and the pause to be the corresponding icons. And same thing with the mute and unmute. Because this is not an SVG course and a React audio player course, I'm going to use the React icons library, particularly Font Awesome. So if I just use the search functionality and start looking for play, I'm going to use the play circle, I'm gonna use the fa pause circle, fa volume, I'm gonna use the volume mute and volume up. I've already installed React icons, so I'm gonna do import from react icon slash fa, and then I'll import fa play circle, fa pause circle, fa volume mute, fa volume up. Next, let's go back to the JSX. And in that button where we toggle the play state, we'll replace the pause string with fa pause circle, and the play with fa play circle. We will do the same thing for the mute button. So we'll change the unmute to be fa volume mute, and the mute to be fa volume up. If we go back to our browser, we'll see that now instead of the play text, we have that play icon, and that changes when we press it. And then same thing for the mute and unmute states. However, let's open up Safari and test this on VoiceOver. VoiceOver on Safari, React app, window, React. [1:34] In React app, web content, heading level, and a main button. You are currently on a button. To click this button, VoiceOver off. As you can see, it just announces button. The reason for this is because icons don't have text unless we provide it to them. So let's go back to React icons and go to the GitHub page. I want you to see if there's any documentation about accessibility and adding alt text. If I go down to the configuration section, I notice that there is a title prop. And that title prop provides an icon description for accessibility. So let's use that title to add back in that text. So on every single Font Awesome icon, we'll add a title prop.

[2:14] So fa pause circle will have a title of pause.

[2:17] Fa play circle will have a title of play. The volume mute icon will have unmute. And the volume up will have mute. Let's go back to our browser and test this. VoiceOver on Safari, React app, in React app, heading level, and a main button. You are currently on a button. To click this button, VoiceOver off.

[2:38] So as you can see, that doesn't actually change much. And this is why you should always test yourself to make sure things are actually accessible. So we're going to change this up again to make sure that we have an accessible icon. So we're going to use the strategy called visually hidden. Visually hidden is a technique used to hide text from sighted users. But if that context is needed for screen reader users, it makes sure that it's still available to them. This is an alternative to using display none or visibility hidden, which completely removes it from the accessibility tree. We're going to copy and paste this CSS and put it into our app.css file. Instead of adding text to the icons, we are going to use aria hidden equals 1 to hide those from the DOM. We're going to wrap every icon inside of a React fragment. And then above the icon, we are going to add a span with a class name equals visually hidden, and then add the text inside that span. So in the pause circle, we're going to put some visually hidden text of pause, play circle, visually hidden text of play. For the volume mute icon, we're going to have visually hidden text of unmute. And then for the volume up icon, we're going to have the visually hidden text of mute. So now if we go back to Safari and test this. VoiceOver on Safari, React app window, in React heading end of main, play button. You are currently on a button. To click this button, press control option space, VoiceOver off. You'll see that the button announces properly. So to summarize, we replaced the text with a corresponding icon from React icons library. We made sure that all of those icons had an aria hidden equals 1. And then we created a visually hidden span to make sure that all of those buttons had accessible names.