Accessibility for the web - introduction to ARIA
Tags: webdev, tutorial, javascript, react
Published: 2020-08-17 19:58:25

In the last article, we talked about `HTML5` and how important is for screen readers that we use `semantic HTML`when writing code. Today we're going to look at `ARIA`, which can supplement markup so that widgets and interactions commonly used in our applications can be passed to `assistive technologies`. You've probably heard about it but what exactly is `ARIA`?

>*Accessible Rich Internet Applications (ARIA) is a set of attributes that define ways to make web content and web applications (especially those developed with JavaScript) more accessible to people with disabilities.* **(MDN)**

In simpler terms, they are attributes which we add to out `HTML` tags. These attributes provide extra information about elements that are otherwise non-semantic and give screen readers a hard time when trying to `translate` them. An important point to make is that `they do not replace HTML5` and they should only be used when `semantic elements` are not available to us. What do I mean by that? Let's build on an example:

**WRONG**
```javascript
<header>
 <ul>
  <li>About</li>
  <li>Portfolio</li>
  <li>Contact</li>
 </ul>
</header>
```
We have a navigation build with an unordered list, inside of a header. This has no meaning for a screen reader and it will read the list out-loud, without knowing we meant to convey a navigation menu (the user will hear something along the lines: `list with there items`).

**BETTER**
```javascript
<header>
 <div role="navigation">
  <ul>
   <li>About</li>
   <li>Portfolio</li>
   <li>Contact</li>
  </ul>
 </div>
</header>
```
We can make the code more accessible by using the `"role" ARIA attribute`. Now the screen user will know that it is reading a navigation (the user will hear something like: `navigation with three items`). Much better, right? But although our problem is solved, the solution is not quite right since `HTML5` offers a `nav` semantic element, so if we want to implement the best way, we would write something like:

**THE BEST**
```javascript
<header>
 <nav>
  <ul>
   <li>About</li>
   <li>Portfolio</li>
   <li>Contact</li>
  </ul>
 </nav>
</header>
```
The effect will be identical for the user and he will hear the same `translation`. Of course, this is a very simplistic example of using an `ARIA` attribute so let's look at another one. 

Let's implement a checkbox using the native `input` HTML element:

```javascript
<label>
 <input type="checkbox">
 Agree with the terms and services
</label>
```

When a screen reader encounters this code, it will tell the user that it's a checkbox, it will read the label and it will also announce the state of the checkbox (if it's checked or unchecked). But let's say we must implement a custom checkbox and we can't use the `input` element but the `div` one:

```javascript
<div id="checkbox" checked>
 Agree with the terms and services
</div>
```

A screen reader will give no indication to the user that this div is meant to be a checkbox. Best case scenario, it will read the text inside of the div but it won't say anything about the role of the element or what its state is (checked or unchecked). Notice I used the words `role` and `state`. We can make this code screen reader friendly by adding ARIA attributes that specify the `role` and the `state` of the element:

```javascript
<div role="checkbox" aria-checked="true">
 Agree with the terms and services
</div>
```
 By adding the extra pieces of information to the `div`, the screen reader can now tell the user that it encountered a `checked checkbox`. Great, isn't it?

Other examples of `role attributes` are: 
- `button`
- `scrollbar`
- `searchbox`
- etc

Other examples of `state attributes` are:

- `aria-disabled`
- `aria-grabbed`
- `aria-autocomplete`
- etc

The list of attributes is of course bigger than this and if you would like to learn more about `ARIA`, you can read this super comprehensive [resource](https://www.w3.org/WAI/PF/aria-1.1/) offered by W3C (World Wide Web Consortium).

*Image source: energepic/ @energepic-com-27411 on Pexels*