Go Back

ARIA (Accessible Rich Internet Applications)

What is ARIA?

ARIA (Accessible Rich Internet Applications) is a set of attributes that help make web content and applications more accessible to people with disabilities. It's like adding subtitles or descriptions to your interface so that assistive technologies like screen readers can understand what's happening.

Think of it this way: if you're watching a movie with your eyes closed, you'd need someone to describe what's happening on screen. ARIA does something similar for assistive technologies - it provides the information they need to understand and interact with your web content.

ARIA was developed by the Web Accessibility Initiative (WAI) of the World Wide Web Consortium (W3C) to address challenges in dynamic content and advanced user interface controls that go beyond what standard HTML can handle.

Why ARIA Matters

ARIA helps you create web applications that work for everyone, not just people who can see and use a mouse. It ensures that people using screen readers, voice control, or other assistive technologies can understand and interact with your content.

It also helps you meet accessibility standards, avoid legal issues, and reach a broader audience while creating more inclusive, professional applications.

Core Concepts of ARIA

ARIA is built around three main concepts:

Roles define what an element is or does - like telling a screen reader "this is a button" or "this is a navigation menu."

States describe the current condition of an element - like "this checkbox is checked" or "this menu is expanded."

Properties define characteristics or relationships between elements - like "this button controls that panel" or "this input has an error message."

These attributes don't change how your interface looks or works for sighted users, but they provide critical information to assistive technologies so they can help users understand and interact with your content.

ARIA Roles

ARIA roles define the purpose of an element. They can override the native role of an HTML element or provide a role when no native HTML element exists for that purpose.

Main Categories of Roles

Landmark roles identify regions of a page, helping users navigate to different sections:

<div role="navigation">Main Menu</div>
<div role="main">Main content</div>
<div role="complementary">Sidebar content</div>

Widget roles define common interactive patterns like buttons, tabs, and menus:

<div role="button">Click me</div>
<div role="tablist">
  <div role="tab">Tab 1</div>
  <div role="tab">Tab 2</div>
</div>

Document structure roles describe structures within content like headings and lists:

<div role="heading" aria-level="1">Main Heading</div>
<div role="list">
  <div role="listitem">Item 1</div>
  <div role="listitem">Item 2</div>
</div>

Live region roles indicate areas that update dynamically, like notifications or status updates:

<div role="alert">Form submitted successfully!</div>
<div role="status" aria-live="polite">Loading results...</div>

ARIA States and Properties

States and properties provide additional information about elements that help assistive technologies understand what's happening.

Common ARIA States

aria-expanded indicates if a collapsible element is expanded or collapsed:

<button aria-expanded="false">Show More</button>

aria-checked indicates the checked state of checkboxes, radio buttons, and similar controls:

<div role="checkbox" aria-checked="true">Agree to terms</div>

aria-disabled indicates if an element is disabled and can't be interacted with:

<button aria-disabled="true">Submit</button>

aria-selected indicates the selected state in widgets like tabs or list items:

<div role="tab" aria-selected="true">Active Tab</div>

Common ARIA Properties

aria-label provides an accessible name for elements without visible text:

<button aria-label="Close dialog">X</button>

aria-labelledby references another element that serves as the label:

<div id="heading">User Settings</div>
<div role="region" aria-labelledby="heading">...</div>

aria-describedby references an element that provides additional description:

<input type="text" aria-describedby="password-requirements">
<div id="password-requirements">Password must be 8 characters...</div>

aria-hidden hides content from assistive technology when it's purely decorative:

<div aria-hidden="true">Decorative content</div>

Live Regions

ARIA live regions inform assistive technology when content changes dynamically:

<div aria-live="polite">This content updates automatically</div>
<div aria-live="assertive">This important update interrupts the user</div>

Live region attributes include:

  • aria-live: Defines politeness level ("off", "polite", or "assertive")
  • aria-atomic: Indicates whether the entire region should be announced
  • aria-relevant: Specifies what types of changes are relevant

ARIA Best Practices

The First Rule of ARIA

"No ARIA is better than bad ARIA."

Always consider if you can use a native HTML element before using ARIA. Native HTML elements have built-in accessibility features that work automatically.

When to Use ARIA

ARIA should be used in these situations:

Enhancing native HTML semantics when native semantics aren't sufficient for your needs.

Making dynamic content accessible for content that updates without page refreshes, like live chat or real-time data.

Creating complex widgets when standard HTML elements don't provide the functionality you need.

Addressing known accessibility issues to fix browser or assistive technology bugs.

When Not to Use ARIA

Avoid using ARIA when:

Native HTML can do the job - always prefer semantic HTML elements like <button>, <nav>, or <header>.

You don't fully understand the implications - incorrect ARIA can actually make accessibility worse.

You can't make the element fully functional with keyboard - ARIA doesn't add keyboard behavior, so you need to implement that separately.

Common ARIA Patterns

Here are some common design patterns and how ARIA makes them accessible:

Accessible Tabs

<div role="tablist">
  <button role="tab" aria-selected="true" aria-controls="panel1" id="tab1">Tab 1</button>
  <button role="tab" aria-selected="false" aria-controls="panel2" id="tab2">Tab 2</button>
</div>
<div id="panel1" role="tabpanel" aria-labelledby="tab1">Panel 1 content</div>
<div id="panel2" role="tabpanel" aria-labelledby="tab2" hidden>Panel 2 content</div>

Accessible Modal Dialog

<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">
  <h2 id="dialog-title">Confirmation</h2>
  <p>Are you sure you want to delete this item?</p>
  <button>Cancel</button>
  <button>Confirm</button>
</div>

Accessible Dropdown Menu

<div>
  <button aria-haspopup="true" aria-expanded="false">Menu</button>
  <ul role="menu" hidden>
    <li role="menuitem">Option 1</li>
    <li role="menuitem">Option 2</li>
    <li role="menuitem">Option 3</li>
  </ul>
</div>

Accessible Form Validation

<label for="username">Username</label>
<input id="username" aria-required="true" aria-invalid="false">
<div id="username-error" role="alert" aria-live="assertive"></div>

Testing ARIA Implementation

To ensure ARIA is implemented correctly:

  1. Use automated testing tools: Tools like Axe, WAVE, or Lighthouse
  2. Test with screen readers: NVDA, JAWS, VoiceOver, or TalkBack
  3. Verify keyboard accessibility: Ensure all interactive elements are keyboard operable
  4. Conduct user testing: Get feedback from people who use assistive technology
  5. Validate against ARIA specifications: Check for proper attribute values and combinations

Common ARIA Mistakes

Some frequent errors when implementing ARIA:

Redundant roles happen when you add roles that duplicate native semantics:

<!-- Redundant -->
<button role="button">Click me</button>

<!-- Better -->
<button>Click me</button>

Conflicting semantics occur when you create confusion with contradictory roles:

<!-- Confusing -->
<h1 role="button">Heading</h1>

<!-- Better -->
<div role="heading" aria-level="1" tabindex="0">Heading</div>

Orphaned ARIA attributes happen when you use states and properties without appropriate roles:

<!-- Missing role -->
<div aria-checked="true">Option</div>

<!-- Better -->
<div role="checkbox" aria-checked="true">Option</div>

Missing keyboard support occurs when you add ARIA without corresponding keyboard functionality:

<!-- Has ARIA but not keyboard operable -->
<div role="button" onclick="doSomething()">Click me</div>

<!-- Better -->
<div role="button" onclick="doSomething()" tabindex="0" onkeydown="handleKeydown(event)">Click me</div>

Getting Started

If you want to improve your ARIA implementation, begin with these fundamentals:

Start by using semantic HTML elements like <button>, <nav>, or <header> whenever possible.

Only add ARIA when you need to enhance native HTML semantics or create complex widgets.

Test your implementation with screen readers and other assistive technologies.

Make sure all interactive elements work with keyboard navigation.

Remember that ARIA doesn't add functionality - it only provides information to assistive technologies.

By using ARIA appropriately, you can make rich internet applications accessible to a wider audience, including those who use assistive technologies. The key is to start with good semantic HTML and only add ARIA when you need to enhance or extend what's already there.