Deep Dive into WAI-ARIA: Roles, States, and Properties

Explore the advanced usage of ARIA roles, states, and properties to enhance HTML semantics and make dynamic web applications more accessible. Understand how to apply these concepts with precision, and the pitfalls to avoid.

ShareShare

Deep Dive into WAI-ARIA: Roles, States, and Properties

In the era of dynamic web applications, HTML must often be extended beyond its native capabilities. Web developers frequently design interactive components like tabs, modals, carousels, and live updates—features that are not natively supported in semantic HTML. This gap is bridged by WAI-ARIA, an acronym for Web Accessibility Initiative - Accessible Rich Internet Applications.

ARIA is a set of attributes that can enhance HTML by adding:

  • Meaning through role
  • Status with aria-*
  • Interactivity via aria-expanded, aria-checked, and similar attributes

These attributes empower assistive technologies like screen readers to comprehend and announce complex user interfaces. However, they should be used judiciously and correctly. This in-depth guide provides a comprehensive understanding of when and how to use ARIA roles, states, and properties, supported by practical examples and highlighting common mistakes.


The Fundamental Rule of ARIA

The first rule of ARIA is: Don't use ARIA if you can use native HTML. HTML5 already offers a wide array of semantic elements. For instance, instead of using div role="button", use the <button> tag. Similarly, prefer <nav> over div role="navigation" and <h1> to <h6> in place of div role="heading". ARIA should enhance, not replace, semantic HTML.


ARIA Roles

ARIA roles provide a description of the purpose of an element. Examples include role="button", role="dialog", role="tabpanel", role="alert", and role="navigation". These roles help assistive technologies understand the function of an element within the application's context.

Consider this example of a tab component:

<div role="tablist">
  <button role="tab" aria-selected="true">Home</button>
  <button role="tab" aria-selected="false">Profile</button>
</div>
<div role="tabpanel">Tab content here</div>

In the above example, the ARIA roles and attributes define a tab structure. The role="tablist" signifies a collection of tabs encapsulated within a div. Each tab is represented by a button with role="tab". The aria-selected attribute indicates the current active tab. Lastly, role="tabpanel" represents the container for the tab content.


ARIA States

ARIA states describe the current conditions of elements. Examples include aria-checked for checkboxes, aria-expanded for menus or accordions, and aria-disabled for non-interactive states.

Consider the following example:

<button aria-expanded="true" aria-controls="menu">Menu</button>
<ul id="menu" hidden>...</ul>

In this example, aria-expanded represents the state of the menu—whether it is open or closed. The aria-controls attribute associates the button with the element it controls, in this case, the 'menu' element. These states must be updated dynamically via JavaScript when the user interacts with the components.


ARIA Properties

ARIA properties define relationships and descriptions between elements. These include aria-labelledby, aria-describedby, and aria-controls.

For example, consider a modal:

<div role="dialog" aria-labelledby="dialog-title" aria-describedby="dialog-desc">
  <h2 id="dialog-title">Delete item</h2>
  <p id="dialog-desc">Are you sure?</p>
</div>

In this modal, the role="dialog" informs assistive technologies that the div is a dialog box. The aria-labelledby and aria-describedby properties link the dialog box to its title and description, respectively. These associations provide context to screen readers, improving the user's understanding of the dialog's purpose.


Live Regions

ARIA live regions allow assistive technologies to announce updates to dynamic content, such as status updates or notifications.

<div role="status" aria-live="polite">Saving...</div>

In this example, role="status" and aria-live="polite" indicate that the div contains a status message to be announced when the user is idle. If the message needs to be announced immediately (for instance, error messages), aria-live="assertive" should be used.


Labeling Elements

For non-text elements such as icons or SVGs, use aria-label or aria-labelledby to provide descriptive labels:

<button aria-label="Close menu">
  <svg>...</svg>
</button>

In this button component, the aria-label provides a text alternative to the non-text content, enhancing the button's accessibility.


Complex Components

The use of ARIA is crucial when building complex components like tabs, sliders, trees, accordions, modals, alerts, tooltips, menus, comboboxes, and multiselect lists. While some libraries and frameworks like React Aria, Reach UI, and Radix provide out-of-the-box solutions, developers can also follow their patterns to implement accessible components.


Common Anti-Patterns

Misuse of ARIA can lead to accessibility barriers if not handled properly. Common anti-patterns include:

  • Using div role="button" without providing keyboard support
  • Applying aria-hidden="true" to visible elements
  • Incorrect hierarchy of roles, such as placing a tab outside a tablist
  • Using ARIA attributes instead of fixing poorly structured HTML
  • Failing to update aria-* states dynamically based on user interaction

Real-World Usage

Many large-scale web applications use ARIA to enhance accessibility. GitHub, for example, uses aria-expanded and aria-controls in its dropdown menus and live region announcements in issue comments. Airbnb uses role="dialog" for its dialogs, with properly labeled headings and interactive filters enhanced with aria-pressed and aria-checked.


Tools for Testing Accessibility

To evaluate the accessibility of your application, tools like Chrome Accessibility Tree, Axe DevTools, Lighthouse, and screen readers like VoiceOver, NVDA, and JAWS can be incredibly helpful.


Conclusion: Speak the Language of Assistive Technologies

ARIA serves as a bridge between your user interface and the assistive technologies that can make it more accessible. When used correctly, it can significantly enhance the user experience. However, when misused, it can lead to confusion.

Remember to stick with native HTML elements whenever possible, supplementing them with ARIA as necessary. Regular testing is key to ensuring your application's accessibility. After all, accessibility is not just about using the correct attributes—it's about enabling clear and effective communication with your users.

Subscribe for Deep Dives

Get exclusive in-depth technical articles and insights directly to your inbox.

about

Ehsan Hosseini

Ehsan Hosseini

me [at] ehosseini [dot] info

Staff Software Engineer and Tech Lead with a track record of leading high-performing engineering teams and delivering scalable, end-to-end technology solutions. With experience across web, mobile, and backend systems, I help companies make smart architectural decisions, scale efficiently, and align technical strategy with business goals.

© 2025 Ehsan Hosseini. All rights reserved.