5 Rules of ARIA
Tags: a11y, html, javascript, beginners
Published: 2023-02-25 13:08:53

Have you ever heard about ARIA? It might sound weird and maybe even intimidating at first. 

In this post, I'd like to talk about the 5 essential rules of ARIA.

## What does ARIA stand for?

Let's start first from the meaning of this acronym.
ARIA - stands for **A**ccessible **R**ich **I**nternet **A**pplications. 
It's a set of _roles_ and _attributes_ that define ways to make web content and web applications (especially those developed with JavaScript) more accessible to everyone. 

There are 5 essential rules of ARIA.


---

## First Rule - Don't use ARIA (unless you don't have a choice)

---

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w22p7w23r28n45hsqvlz.jpg)

It might sound a bit counter-intuitive, but rather than creating our own custom elements and trying to make them accessible by adding ARIA attributes, we should use native HTML elements instead. 

Instead of creating a button using `<div>`

```html
<div role=“button” tabindex=“0” aria-pressed=“false”>Open</button>
```

It'd be much better to use native HTML `<button>` instead

```html
<button type=“button”>Open</button>
```

If we can use a native HTML element, then we should do so. We should reach out to ARIA as a last resort.

---

## Second Rule - Prefer native semantics over ARIA

---



We should always prefer native HTML elements over custom elements with ARIA attributes.


Let's say, we'd like to create a title. In such case, it'd be better if we use a native `<h2>` HTML element rather than a `<div>` with ARIA attributes.


Not a good idea.
```html
<div role="heading" aria-level="2">Title text</div>
```


We should prefer to use native HTML elements instead.
```html
<h2>Title text</h2> 
```


**NOTE:** 
If we create an interactive element, let's say a `<button>`, using `<div>`. 
In addition to using proper ARIA attributes, we will need to add appropriate interaction behavior (e.g. click handler) using JavaScript. 

That's why, in the case of a `<button>`, it is much better and easier to just use a native element. 
```html
<button type=“button”>Open</button>
```

---

## Third Rule - All interactive elements must be usable with a keyboard

---


All interactive elements, whether it be a custom element we created or a native HTML element, must be usable with both a mouse and a keyboard.

If we created a widget that can be clicked, tapped, dragged, slid, or scrolled. A user should be able to use it with both a mouse and a keyboard.

If using `role=button`, on a custom element, the element must be able to receive focus and a user must be able to activate the action associated with the element using both the `enter` (on WIN OS) and the `space` key.

---

## Fourth Rule - Do not use `role="presentation"` or `aria-hidden="true"` on a focusable element

---


Using `role="presentation"` or `aria-hidden` on a focusable element might result in some users focusing on it and getting inaccurate information. In some cases, users won't even be able to discover such elements.


Using either of these on a focusable element might result in some users focusing on 'nothing'.

```html
<button role=“presentation”>press me</button> 

<button aria-hidden=“true”>press me</button>
```

---

**NOTE:** Setting `aria-hidden` on a parent/ancestor element, of a visible interactive element (e.g. `<button>`), will also hide an element from assistive technologies (e.g. screen reader).

```html
<div aria-hidden="true">  
   <button>press me</button> 
</div> 
```

---

**NOTE:** We can use `aria-hidden` on an element, as long as it's not focusable.

We can set `tabindex="-1"` on a focusable element that will remove it from the tab order, so it won't be focusable by a keyboard, but we can still be able to focus it using JavaScript if we want to.

``` html
// tabindex="-1" removes the button from the tab order  
<button tabindex=“-1” aria-hidden=“true”>press me</button> 
```

---

**NOTE:** If we use `display: none` or `visibility: hidden` (either on an element or on the element's ancestor) it won't be focusable and will be removed from the accessibility tree. 
That is, screen readers won't be able to discover it. In such case, we don't need to add `aria-hidden` or negative tabindex on such an element.

CSS
```CSS 
.hidden-btn {display: none;} 
```
HTML
```HTML
<button class=“hidden-btn“>press me</button> 
```

---

## Fifth Rule - All interactive elements must have an accessible name

---


Accessible name, is a name of a UI element. Each platform has its own accessibility API which provides such property. The value of the accessible name may be derived from a visible or invisible property on an element.

**Visible property** - visible text of an element. Let's say, a visible text on a button.

**Invisible property** - ARIA attributes such as `aria-label` or `aria-labelledby`

Let's take a look at a few examples, so we can understand it better.


Here the text "_press me_" is the visible text of the `<button>` and as such, can be used as an accessible name.
```html
<button>press me</button>
```

When the `<button>` receives focus, a screen reader may announce something like "_press me, button_" concatenating a role (_button_) of the element and its name (_press me_).

The order of concatenation and a role description depends on a platform's accessibility API and the assistive technology (e.g. screen reader) that is used.

---

The `<input>` in the code examples below has a visible label "_username_" , but no accessible name

```html
username <input type="text"> 
``` 
or 
```html
<span>username</span> <input type="text">
```

Here the `<input>` has a visible label but it can not be used as an accessible name. It cannot be associated with the `<input>`. 
In such case, a screen reader won't be able to announce the accessible name of the `<input>`. That would be, an accessibility violation.

---

In comparison, this `<input>` has both a visible label and an accessible name.

Using `<for>` attribute
```html
<label for="userNameId">username</label> 
<input type="text" id="userNameId"> 
```

or 

Wrapping it with a `<label>`
```html
<label> 
  username  
  <input type="text"> 
</label> 
```

In the examples above, we use a `<label>` element to provide an accessible name for our `<input>`.

---

### What if we can't use `<label>` or `for` attribute?
In such a case we might use ARIA attributes, 
namely `aria-label` or `aria-labelledby`.

Using `aria-label`
```html
<input type="text" aria-label="Username"> 
```

Using `aria-labelledby`
```html
<span id="fldUsrnm">username</span>  


<input type="text" aria-labelledby="fldUsrnm">
```

In this situation, we use ARIA as a last resort, which is perfectly fine.

---

##Conclusion
There you have it the 5 rules of ARIA

1. Don't use ARIA (unless you really have to)

2. Prefer native semantics over ARIA

3. All interactive elements must be usable with a keyboard

4. Do not use role="presentation" or aria-hidden="true" on a 
focusable element

5. All interactive elements must have an accessible name

Of course it's not all, and we barely scratched the surface. Nevertheless, I hope it's a beginning of a better understanding ARIA.

I hope this post was useful for you as a reference.