Performance & UX
·6 min read

ARIA Accessibility: What Is It, When to Use It, and How to Get Started

What is ARIA?

ARIA stands for Accessible Rich Internet Applications (ARIA). When we write well-structured HTML without altering the default behaviors, our websites become naturally accessible.

But sometimes, what we're building requires more complexity.

We might have error messages, live content updates, or other widgets. While these components are great for user experience, they’re far from the original document-based behavior designed for browsers and markup languages.

They need a little help — and that’s where Accessible Rich Internet Applications (ARIA) comes in.

This guide will cover the main features defined in the ARIA specification when you should (and shouldn’t) use ARIA to supplement your semantic HTML, and how to test your authored ARIA.

Prerequisites for understanding ARIA

Before diving in, you should know or explore the following items. They'll make it easier to understand what ARIA is, as well as when and why you'd use it.

ARIA and the Web Accessibility Initiative (WAI)

Written entirely as WAI-ARIA (Web Accessibility Initiative — Accessible Rich Internet Applications), ARIA is a specification defined by the W3C.

This specification outlines roles and attributes designed to change HTML elements' exposed meaning (commonly referred to as “semantics”). Roles define what an element is or does, while attributes affect and describe interactions.

The goal is to help assistive technologies present the content and support interaction in a way that matches expectations.

Using ARIA is particularly valuable for describing elements beyond HTML's current capabilities or lacking full support.

Stay on Top of New Tools, Frameworks, and More

Research shows that we learn better by doing. Dive into a monthly tutorial with the Optimized Dev Newsletter that helps you decide which new web dev tools are worth adding to your stack.

ARIA roles

By default, semantic HTML elements have an implicit role that defines what an element is or does. Available definitions are added to the accessibility tree and later interpreted by a screen reader or another tool.

The HTML tag and the role are synonymous with some elements, like <form> and the role form, or <table> and the table role.

Other elements have roles with complimentary, but not interchangeable, names. Two examples are <progress>, which has the progressbar role, and <hr>, which uses the separator role.

However, some elements don’t have implicit roles. <span> or <div>, for instance, both have generic as their role. In many cases, this value returns null. This doesn't give someone using assistive technology any context to understand what the element does or why it's on the page.

That’s where ARIA roles can be useful.

ARIA roles are defined in an HTML element using role=“name”, but replacing name with a role from the ARIA specification. It works by overriding the element's native role semantics in the accessibility tree.

<div role=“status”>An update for you!</div>

A screen reader will report the element as a status in the proceeding code.

Important note: Roles only change the native role semantics of the host element. They don’t change how the element looks or behaves for people who aren’t using assistive technology (i.e., you'll still be able to press a <button> even if you add a different ARIA role).

Where to find a list of ARIA roles

ARIA states and properties

Along with roles, the WAI-ARIA specification provides a set of states and properties (collectively called "attributes") that affect and describe interactions. These attributes are often, but not always, used to support existing ARIA roles on a page.

All ARIA attributes follow the same naming convention, with the state or property name beginning with the string aria-:

aria-[state|property]="name"

In the preceding example, name represents a support state or property.

Properties

ARIA properties define the purpose of an HTML element in the accessibility tree or describe the relationship between the host element and other elements on the page.

Once set, properties typically don't change (unlike ARIA states).

One popular property is aria-label, a string value that labels an interactive element. aria-label is frequently used to override an existing label with more precise information intended for people using a screen reader.

The following is an example from the Accessibility Developer Guide:

<button>Zoom image</button>

Someone looking at the page built with the preceding code will see a button with text that reads "Zoom image." They can quickly click, check it out, and move on.

But someone using a screen reader may not understand what the button does and what will happen if they interact with it.

Adding an aria-label can help fill the gap:

<button aria-label="Zoom image: opens a high-resolution version, press Esc to close">
    Zoom image
</button>

Using `aria-label` should be a last resort

Generally, semantic HTML elements have a way to provide labels — such as <label> for inputs, <caption> for tables, or alt attributes on <img> tags. Using aria-label should be a last resort.

States

ARIA states define the current condition of HTML elements in the accessibility tree. When compared to ARIA properties, states are more likely to change throughout the application lifecycle and this shift is generally programmed in JavaScript.

Commonly used ARIA states include aria-disabled, aria-hidden, aria-checked, aria-selected, and more.

The following example uses aria-checked to indicate whether the element is checked (true) or unchecked (false):

<ul>
  <li>
    <div role="checkbox" aria-checked="false">
      Ketchup
    </div>
  </li>
  <li>
    <div role="checkbox" aria-checked="true">
      Mustard
    </div>
  </li>
</ul>

The element with the current checked state signifies our preferred condiment ("Mustard" in the preceding code).

ARIA attributes

Knowing when not to use ARIA

“No ARIA is better than Bad ARIA” is a common saying in the accessibility community. It’s even at the top of the ”Read Me First” page in the W3C’s ARIA Authoring Practices Guide (APG).

Because ARIA can cover up an element’s original semantics or content, it gives a lot of power to the developer writing it. So websites with incorrectly implemented ARIA might override native accessibility semantics, which can cause more issues than websites without ARIA.

The following example (adapted from the APG) shows the potential danger:

<!-- 🚨 Invalid HTML -->
<ul role=“navigation”>
<!-- This is a navigation region, not a list. -->
    <li><a href=“/”>Home</a></li>
    <li><a href=“/about”>About</a></li>
    <li><a href=“/contact>Contact</a></li>
<!-- Error! Previous list items are not in a list. -->
</ul>

🚧 Important note: Even though it’s invalid, this HTML will render and visually look like a list (browsers are very forgiving). That’s why it’s essential to test and validate your HTML and authored ARIA.

In the preceding code, we override the <ul> tag’s native list role by using ARIA to define role="navigation" on the element.

navigation is a landmark role, meaning it provides a way to identify the structure of a webpage— not recognize list items. And because the ARIA role is prioritized over the native semantics by the accessibility tree, changing this role invalidates our HTML.

Instead of changing the role, we can nest a list inside of navigation using semantic HTML (no ARIA needed):

<!-- ✅ Valid HTML -->
<nav>
  <ul>
    <li><a href=“/”>Home</a></li>
    <li><a href=“/about”>About</a></li>
    <li><a href=“/contact>Contact</a></li>
  <ul>
</nav>

More accessible navigation samples, including popup menus, are in Heydon Pickering’s “Building Accessible Menu Systems” article in Smashing Magazine.

Questions to ask when considering using ARIA attributes

Is there a native HTML element or attribute I can use?

According to the W3C, this is the first rule of ARIA use:

"If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.”

Let’s look at a button.

The following shows what the W3C refers to as a “redundant role”:

<!-- Avoid doing this 🙅🏼‍♀️ -->
<button role=“button”>Interact with me!</button>

Specifying this role is unnecessary, as the <button> already has the button role. Fortunately, adding this role probably won’t have any unexpected side effects beyond more verbose markup.

Where you run into problems is if you try to build a button using a generic element like a <div>:

<!-- Avoid doing this 🙅🏼‍♀️ -->
<div role=“button”>Interact with me!</div>

<!-- Do this instead 🙋🏼‍♀️ -->
<button>Interact with me!</button>

Native elements have built-in keyboard accessibility, roles, and states. When you use ARIA instead, you also take responsibility for mimicking these behaviors.

Does the ARIA I’m authoring change the native semantics of this element?

The second rule of ARIA use: If you need to use ARIA, try to avoid changing native semantics.

The W3C uses the example of wanting to build a heading that’s a tab:

<!-- Don’t do this 🙅🏼‍♀️ -->
<h2 role=“tab”>Important tab</h2>

If you need to change the semantics, consider swapping the host element for one with the role you want. From there, you can nest your other elements.

For the preceding code, that means replacing the <h2> (which has a heading role) with a generic, non-semantic tag where you can add the tab role. Then, nest your heading:

<!-- Do this instead 🙋🏼‍♀️ -->
<div role=“tab”>
    <h2> 
        Important tab 
    </h2>
</div>

If you want to write accessible tabs, Inclusive Components' Tabbed Interfaces is a solid reference.

Pattern guides for common components

The APG also includes a comprehensive collection of interactive component pattern guides. They cover commonly built and headache-inducing components, such as accordions, modals, sliders, tooltips, and many more.

These guides describe the pattern and provide an example. Each example page contains the following:

  • Accessibility features list
  • Any necessary keyboard support
  • Table of the ARIA features used
  • All source code (and a CodePen link)

For reference: Breadcrumb and Breadcrumb Example.

Testing your authored ARIA

Browsers do their best to render something passable on the page, even if the underlying HTML isn't valid. Just because everything looks visually correct doesn't automatically mean it's accessible.

You're going to want to test what you wrote, and the following are just a few ways to do that:

ARIA browser compatibility and feature support

Many ARIA features aren't fully supported in modern browsers. Beyond browsers, feature support can change based on the operating system, assistive technology, and more. That's part of what makes native semantic HTML elements more reliable.

If you need to use ARIA, websites like Accessibility Support can help you identify potential issues.

FAQs

When to use ARIA

Use ARIA attributes when standard HTML elements alone don't provide enough semantic information for assistive technologies like screen readers. Some situations where ARIA can help include using roles to clarify the purpose for divs or spans that behave like widgets, states to inform users of dynamic interactions like collapsing sections or toggling buttons, properties to associate text labels with non-text elements when not visually linked, and live regions to announce real-time updates that should be immediately conveyed to users.

Article written by

Carolyn Stransky

Carolyn is a journalist and software engineer based in Berlin. She's also a conference speaker and technical writer, interested in topics such as accessibility and design systems.

More posts
Carolyn Stransky taking a selfie in a mirror.

Join the discussion

Hit your website goals

Websites success stories from the Prismic Community

How Arcadia is Telling a Consistent Brand Story

Read Case Study

How Evri Cut their Time to Ship

Read Case Study

How Pallyy Grew Daily Visitors from 500 to 10,000

Read Case Study