ARIA States — Dynamic Attributes That Change With User Interaction
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
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