Skip to content

ARIA States — Dynamic Attributes That Change With User Interaction

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about ARIA States. We cover key concepts, practical examples, and best practices to help you master this topic.

ARIA states are dynamic attributes that change based on user interaction or application state, including aria-expanded, aria-selected, aria-pressed, aria-checked, aria-current, and aria-hidden.

In this tutorial, you'll learn about ARIA states and how to update them as users interact with your ARIA-powered widgets.

What You'll Learn

By the end of this lesson, you'll understand the difference between states and properties, know the most common ARIA states, and know how to toggle them with JavaScript in response to user actions.

Why It Matters

States tell screen readers about current conditions that change over time. A button that does not announce its expanded state leaves screen reader users guessing whether content is visible.

Real-World Use

Doda Browser's sidebar uses aria-expanded to indicate whether the navigation panel is open, and Durga Antivirus Pro uses aria-busy on scan result regions while scanning.

ARIA States Overview

flowchart TD
  A[ARIA States] --> B[Interaction States]
  A --> C[Validation States]
  A --> D[Visibility States]
  B --> E[aria-expanded]
  B --> F[aria-selected]
  B --> G[aria-pressed]
  B --> H[aria-checked]
  C --> I[aria-required]
  C --> J[aria-invalid]
  D --> K[aria-hidden]
  D --> L[aria-busy]

Understanding ARIA States

States represent conditions that change in response to user actions or system events. They are typically managed with JavaScript.

aria-expanded

Indicates whether a collapsible element is open or closed:

<button aria-expanded="false" aria-controls="menu-1">
  Settings
</button>
<ul id="menu-1" hidden>
  <li>Profile</li>
  <li>Security</li>
</ul>

When the user clicks, toggle the state with JavaScript:

button.addEventListener('click', () => {
  const expanded = button.getAttribute('aria-expanded') === 'true';
  button.setAttribute('aria-expanded', !expanded);
  document.getElementById('menu-1').hidden = expanded;
});

aria-selected

Indicates which option in a set is currently selected:

<div role="tablist" aria-label="Scan type">
  <button role="tab" aria-selected="true" tabindex="0">Quick</button>
  <button role="tab" aria-selected="false" tabindex="-1">Full</button>
  <button role="tab" aria-selected="false" tabindex="-1">Custom</button>
</div>

aria-hidden

Hides content from the Accessibility tree without removing it visually:

<div id="loading-overlay" aria-hidden="true">
  <p>Scanning...</p>
</div>

aria-busy

Indicates that an element is still loading or updating:

<div role="region" aria-live="polite" aria-busy="true" id="results">
  Loading scan results...
</div>

Updating States With JavaScript

ARIA states must be kept in sync with the visual state:

function toggleMenu(button) {
  const isOpen = button.getAttribute('aria-expanded') === 'true';
  button.setAttribute('aria-expanded', !isOpen);
  const menuId = button.getAttribute('aria-controls');
  document.getElementById(menuId).hidden = isOpen;
}

Common Mistakes

  • Forgetting to update ARIA states: If the visual state changes but the ARIA state does not, screen readers announce incorrect information.
  • Using aria-hidden="false": aria-hidden is false by default. Only set it to true when hiding content.
  • Applying aria-selected to non-selectable elements: Only elements in selection containers should have aria-selected.
  • Using aria-expanded on non-interactive elements: Only interactive controls should have aria-expanded.
  • Not syncing multiple related states: A tab that is not selected should also have tabindex="-1".

Practice and Challenge

1. What is the difference between ARIA states and properties? States change with interaction or system events; properties describe stable characteristics.

2. Which ARIA state indicates an accordion section is open? aria-expanded="true".

3. How do you hide content from screen readers but keep it visible? Set aria-hidden="true".

4. What does aria-busy indicate? That an element is still updating or loading.

5. Challenge: Create a disclosure widget that toggles aria-expanded between true and false and syncs the hidden state of the content panel.

FAQ

Should I use aria-selected or aria-current for navigation links?

Use aria-current for current page links and aria-selected for items within a selectable set like tabs.

Can I use CSS to set ARIA states?

You can set ARIA attributes in CSS, but this is not recommended. Use JavaScript for dynamic state management.

What is the default value of aria-expanded?

There is no default. The attribute should not be present when the element is not expandable.

Do ARIA states affect visual styling?

Only if you write CSS attribute selectors like [aria-expanded='true'].

Can I have multiple selected items with aria-selected?

It depends on the role. For tabs, only one. For listbox with multiple select, multiple items can be selected.

Mini Project

Build a reusable toggle component that uses aria-expanded to communicate state. Include JavaScript that syncs aria-expanded with the content visibility.

What's Next

Continue to Role Attributes to learn how to apply role attributes correctly in HTML.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro