All Topics
ARIA
Roles, States, & Properties

Roles, States, and Properties

The major categories of ARIA attributes are roles, states, and properties. Each one of the attributes fits into a category, such as role="button" or aria-hidden="true".

The ARIA specification (opens in a new tab) details all of the concepts and details of attributes that are available to you. Some are better supported in browsers and Assistive Tech than others–there have been many excellent ideas over the years, without the necessary adoption from browser makers for various reasons.

ARIA Roles

There are multiple types of roles we use in our markup: widget roles that are often interactive, document structure roles that organize content on a page, landmark roles for special navigational landmarks, live region roles for screen reader announcements, and window roles for dialogs.

Many HTML elements have roles built-in, such as <button> and <main>. Role attributes can also be bolted-on to override the default semantics of an element, although you should take care to avoid wiping out a default role unless absolutely necessary.

<button>  <!-- implicit 'button' role -->
<div role="button"> <!-- explicit 'button' role -->

Use <div role> for a custom component if for some reason you can’t use a native HTML element with a role built-in. Why? Because elements with implicit roles provide behavior for free and often support is better.

How to check support for an ARIA role, state, or property

There are many promising ARIA attributes that unfortunately don’t have great support. If you have a use case for something, say aria-autocomplete, here are some recommendations on how to test it:

  1. Check A11ySupport.io (opens in a new tab) to see if the attribute is listed.
  2. Test it in the screen readers that are commonly used (opens in a new tab) with your most popular browsers.
  3. Read up on mailing lists like the WAI-ARIA GitHub (opens in a new tab), NVDA GitHub (opens in a new tab) and WebAIM Email Archives (opens in a new tab).

Using ARIA in CSS selectors

ARIA attributes can provide some helpful selectors in CSS, such as:

<div
    aria-disabled="true"
    aria-label="Subscribe"
    role="checkbox"
    tabIndex={0}
    onKeyUp={keyHandler}
    >
</div>
[role="checkbox"] {
    /* custom checkbox styles here */
}
[role="checkbox"][aria-disabled="true"] {
    /* disabled checkbox styles here */
}

Now, you should really question whether it’s worth it to recreate a checkbox or other custom component when there are default components available for free. But elevating ARIA attributes to the style layer can make them less easy to ignore, and weave accessible state through your culture of styling.

Another use case could include styling off [aria-expanded="true"] (opens in a new tab) state rather than maintaining an .active or similar CSS class to show/hide a group of content items (like a custom dropdown).

You might have other ways of styling or showing/hiding content, such as with React where state variables in React/JSX will apply directly to component markup (rendering it in HTML or not based on conditionals in the code). Or, you might use Tailwind which can (for good and for bad) abstract the web coding experience away from writing CSS selectors at all, let alone things like [aria-busy].

It’s still helpful to have a range of tools in your pocket for manipulating the DOM and UI, and sometimes CSS attribute selectors targeting ARIA roles, states, or properties can do the trick!