What is ARIA?
ARIA, or 'WAI-ARIA' (they're the same thing) is a specification from the W3C, just like the specs for HTML, CSS, etc.
It is a set of element attributes meant to supplement native HTML semantics, particularly (but by no means exclusively) by marking up dynamic content, such as tabs, forms and other user interface elements, or 'live' content, like a Twitter feed.
Let's take a step back and learn a little about the DOM before we dive into how ARIA adds to the information available to users about what the DOM is doing.
The DOM API
![Rich Whitehouse [CC BY-SA 2.5 (https://creativecommons.org/licenses/by-sa/2.5)], via Wikimedia Commons Noesis User Interface rendering a Dicom model of a human head](/img/KPv39Ecwzz-300.jpeg)
Both 'DOM' and 'API' are acronyms that get thrown around a lot. Let's quickly define them.
An Application Programming Interface is a user interface, where the user is a person writing a computer script. It provides you information and functionality from the document or application that you're interacting with.
The Document Object Model is an API that represents an HTML (or XML) document as a traversable tree structure. The elements (and attributes, including text content) within that structure are referred to as 'nodes'.
There are different kinds of attributes we can assign to DOM nodes. There are native attributes, which are provided by the HTML spec, e.g. class, alt, target. There are data- attributes (added in HTML5), which are user-customizable. And there are ARIA attributes.
The main type of information that ARIA (Accessible Rich Internet Applications) provides is contextual information about if and how DOM nodes can update, and what happens when they do.
When to use ARIA
- There is a DOM node (including text) that can or does update without a page refresh being triggered, or
- There is no native semantics element or attribute available to describe how an element can change the DOM.
Don't be redundant
<div role="button"></div>
…is not redundant. If you are using a div as a button, there is no semantic indicator that it is meant to function as a button unless you specify it with the role attribute.
<button role="button" />
…on the other hand, is redundant. The native semantics make it apparent to all concerned that this button is, in fact, a button.
Want to be safe? Test!
![RÁDIÓ ÉS TELEVÍZIÓ ÚJSÁG [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons AT 501 fortepan 56114](/img/Yg_NSpE19O-300.jpeg)
I can't emphasize enough how important it is to test. That's why there are QA departments.
It is wonderful to follow best practices, but even when specification documentation is perfect (it's not), and even when you limit your scope to the latest versions of a few popular clients (don't), and even when your linters catch all the edge cases (they won't), you still make mistakes.
Work with your QA department to determine which screen readers you can test on. There's no replacement for testing!
What ARIA attributes should I use?
Normally I'd tell you to check out the MDN docs, but, as of this writing, a lot of their ARIA documentation is incomplete.
There are a lot of ARIA attributes and properties with varying levels of support. Here are the common, well-supported ones you should know to get your feet wet.
Role
The role attribute specifies what type of component an element represents. Many of the original ARIA roles were turned into semantic elements with the introduction of HTML5; role="main" became the main tag; role="banner" became the header tag, etc. You should still use these if you're not using a main tag or a header tag. The following are common roles that don't have an equivalent in HTML5:
role property | Description |
|---|---|
tablist |
A set of tabs for toggling content. |
tab |
A clickable tab for toggling content. Use with aria-selected to indicate the active tab, and aria-controls to reference the id of the associated tabpanel |
tabpanel |
The content whose visibility is toggled by the associated tab. Remember to toggle the hidden attribute when toggling visibility. |
alert |
An important dynamic message for the user. Steals focus when the display property of the element is updated. |
search |
Applied to a form element that returns search results. |
progressbar |
An element that visually indicates progress. Used with aria-valuenow, aria-valuemin, aria-valuemax, and optionally aria-valuetext (i.e. 'Step 5'). |
dialog |
A dynamic message for the user, such as a modal. Must have an accessible method of exiting the dialog, such as a 'close' button. |
Other ARIA attributes
All ARIA attributes other than role are prefixed with aria-. Once again, there are a great number of ARIA attributes, but the ones that you'll run into most often are below:
| Attribute | Value type | Description |
|---|---|---|
aria-hidden |
Boolean | Hides element from screen readers. |
aria-label |
String | Describes the element's contents. |
aria-expanded |
Boolean | Indicates whether the element is expanded or not, as in the case of a tabpanel. |
aria-required |
Boolean | Used for form elements that require the user to enter a value before the form can be submitted. HTML5, of course, provides us with a native required attribute, but support in assistive technologies has shown to be touch-and-go. |
aria-selected |
Boolean | Indicates that a selectable element has been selected. |
aria-live |
assertive | polite | off |
Indicates that an area has 'live' content, as in the case of a Twitter feed. A value of assertive will cause a screen reader to interrupt a user at any point to read out the new content regardless of other activity, whereas polite will not interrupt mid-sentence or while typing. |
aria-current |
page | step | location | date | time | Boolean |
Indicates that an element in a set is the active indicator, often seen in the case of navigation. If aria-selected is more appropriate, as in the case of a set of tabs, use that. |
There are a lot, but you should know about the role attribute, which labels interactive elements, including tabs, search, form, and grid; and state attributes including aria-live, aria-expanded, and aria-hidden (which differs from the native hidden attribute).