DEV Community

Daniel Carlman
Daniel Carlman

Posted on

Improving React Accessibility with Dynamic Aria-label Props

I've been working as a Front-End Developer for less than a year. While I learned a lot on my first job, I knew that, as a beginner, the real challenge would lie in starting my very own first personal project.

I created React Skill Calculator, a web app that lists skills Front-End Developers should consider learning before trying React. It works like this:

1) You check what technologies you know well.

2) The app calculates a simple score based on your answers.

3) For the unchecked skills, the app returns a list containing useful resources to help you learn them, such as links to tutorials, documentations and also a brief description of the technologies.

React Skill Calculator

Before deploying my project, I wanted to know how accessible the site really was, so I decided to test it using ChromeVox, a screen reader extension for Google Chrome. That was my first time using such technology and I was immensely disappointed with the results. I was barely able to navigate using my keyboard. Most of the text was being skipped. The audio provided by the reader didn't communicate clearly what was expected of users. That's when I knew I'd have to step up my game and build a better mousetrap.

Eventually I came up with a solution using props:

// PARENT COMPONENT

<Button
  onClick={this.toggleButton}
  checked={this.state[skill.id]}
  value={skill.id}
  ariaLabel={`Check if you know ${skill.title}`}
  ariaLabelChecked={`${skill.title} was checked! You checked ${this.state.count} out of ${skills.length} `}
/>
Enter fullscreen mode Exit fullscreen mode
// CHILD COMPONENT

<C.Button
  onClick={() => props.onClick(props.value)}
  checked={props.checked}
  aria-label={props.checked ? props.ariaLabelChecked : props.ariaLabel}
>
{props.checked ? 'OK ✔' : 'Check'}
</C.Button>
Enter fullscreen mode Exit fullscreen mode

The Button component runs the toggleButton function whenever the user clicks on it. This toggles the boolean value of a state object named checked between 0 and 1.

When checked is equal to 0, the button text is "Check".

When checked is equal to 1, the button text is "OK ✔".

Without context, this information isn't very helpful to visually impaired users.

These are the main issues:

1) Users don't know what skill they are checking when focusing on a button element.

While I did use the tabIndex property so the reader could name all the skills, it would still be a hassle for users to have to press Alt + Tab to go back and forth in order to understand what skill that button relates to. Also, that alone doesn't help users overcome the second issue.

2) There is no way of knowing how many skills the users have checked without relying on memory or going back to the beginning of the page.

Once you're past the score counter ("0 out of 20"), you wouldn't be able to tell the score unless you have a great memory or pressed Alt + Tab to go back to it.

So what I did was use props to determine which aria-label should be used. Let's use "HTML" as an example of a skill being checked.

If check equals 0, the AriaLabel prop text will read: "Check if you know HTML".

If check equals 1, the AriaLabelChecked prop text will read "HTML was checked. You checked 1 out of 20".

With the use of dynamic aria-label props, I was able to clearly communicate to users the current score and which button corresponded to which skill. I was finally able to navigate through my application with ease, using only the keyboard.

Accessibility is one the biggest challenges in tech. It's a very empowering tool that is often overlooked. I don't pretend by any means that my project is perfectly accessible to all users, but I feel it's a step in the right direction.

I'm curious to know how other developers have approached this problem. Please leave a comment if you have other ideas that you'd like to share. I'm open to feedback and very interested in learning more about web accessibility features.

Top comments (0)