Beginning Web Accessibility in React
Tags: a11y, react, typescript
Published: 2020-01-29 14:25:50

---
title: Beginning Web Accessibility in React
published: true
date: 2020-01-29 00:00:00 UTC
tags: a11y, accessibility, react, typescript
canonical_url: https://joelmturner.com/blog/beginning-web-accessibility-react
cover_image: https://joelmturner.com/static/d102f4eff31589cf83981771e1070158/315f3/web-accessibility-react-a11y.webp
---

I recently decided to dive into learning accessibility on the web. So many of the great developers that I follow on Twitter advocate for accessibility and I figured it was time to see what it would take. So far, I love it.

If you’re interested in web accessibility I would suggest Gatsby, which gives a lot of win out of the gate and [@MarcySutton](https://twitter.com/marcysutton) who is an accessibility advocate and has a package, [`no-mouse-days`](https://github.com/marcysutton/no-mouse-days) that can disable the cursor on your site or app for a day. Nothing helps me see the cracks like taking away my comfort zone. Time to grow!

There are a lot of resources online to help us learn so there’s nothing new in this post. I just wanted to document what I have found and learned so far.

## Linting Rules for a11y

One of the best ways to get some useful suggestions is to add the plugin, [`eslint-plugin-jsx-a11y`](https://www.npmjs.com/package/eslint-plugin-jsx-a11y) to your project. After I got it installed my editor lit up like New York City at night. Whew, I had some work to do.

## WAI-ARIA

WAI-ARIA is explained well from [MDN](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/WAI-ARIA_basics):

> WAI-ARIA (Web Accessibility Initiative - Accessible Rich Internet Applications) is a specification written by the W3C, defining a set of additional HTML attributes that can be applied to elements to provide additional semantics and improve accessibility wherever it is lacking.

The three main features are Roles, Properties, and States.

### Roles

It’s best to use semantic elements for desired actions. A good example is to use the `button` element for a user action. If we are using a different element to perform the role of a button we can use a role to help out. An example might be an `svg` icon with an `onClick` method.


```html
<svg viewBox="0 0 128 128" onClick="{myOnClickFn}" role="button">
  <path d="M 10 10 H 90 V 90 H 10 L 10 10" />
</svg>
```

Having the role of `button` tells the screen reader that the intention of this icon is to be a button.

Here’s a list from [MDN of all the ARIA roles](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles).

### Properties

Properties let us give an element extra meaning if needed. A common example is in a form input. We may have a visual indicator to show that an `input` is required. Now we can add a data attribute of `aria-required="true"` to let the user know that the input needs to be valid.

```html
<form onSubmit="{onSubmit}">

  <label for="fieldName">Name</label>
  <input name="fieldName" type="text" />

  <label for="fieldEmail">Email</label>
  <input name="fieldEmail" type="email" aria-required="true" />

</form>
```

### States

This is much like states in javascript. We may have a disabled input that will become enabled after validation of a previous field. We can specify the disabled state with `aria-disabled="true"`.

```html
<form onSubmit="{onSubmit}">

  <label for="fieldName">Name\</label>
  <input name="fieldName" type="text" />

  <label for="fieldEmail">Email</label>
  <input name="fieldEmail" type="email" aria-required="true" />

  <label for="fieldSubscribe">Subscribe</label>
  <input name="fieldSubscribe" type="checkbox" checked="false" aria-disabled="true" />

</form>
```

## `tabIndex`

This is one that I vaguely knew about. It turns out that there are three types of values that it can take.

- `tabindex="-1"` negative one or less allows elements to get the focus programmatically instead of through sequential keyboard navigation
- `tabindex="0"` zero allows non-tabbable elements to become tabbable in sequential order by adding focus to them in the document’s source order
- `tabindex="1"` one or more makes the elements tabbable in the specific index order represented by this number

## `onKeypress` handler

For all the user clickable elements we can also provide an onKeyPress that handles an `Enter` or `Return` key on a clickable element. We can use a function to check for that keypress and if it’s is the key we’re looking for we can pass the event to the `onClick` function.

Here’s a great snippet from [John Luke Garofalo’s post about React accessibility](https://dev.to/johnlukeg/make-react-navigation-accessible-again):
{% link https://dev.to/johnlukeg/make-react-navigation-accessible-again %}

```javascript
// attach to an onKeyPress to handle Enter keyboard
// presses in the same way as onClick

export const handleEnterKeyPress = onClick => event => {

  if (event.key === "Enter") {
    onClick(event)
  }

}
```

Here’s that snippet in TypeScript:

```typescript
type HandleKeyPress = (
  onClick: React.EventHandler<React.MouseEvent | React.KeyboardEvent>
) => React.KeyboardEventHandler<HTMLElement | SVGElement>

// attach to an onKeyPress to handle Enter keyboard clicks in the same way as onClick

export const handleEnterKeyPress: HandleKeyPress = onClick => event => {

  if (event.key === "Enter") {
    onClick(event)
  }

}
```

## Conclusion

Hopefully, this helps you dip your toes into the accessibility pond. I have a lot more to learn and implement but I feel like this was a good start. I would love to hear your resources if you have started down this road as well.