WAI-ARIA Reference
Free reference guide: WAI-ARIA Reference
About WAI-ARIA Reference
The WAI-ARIA Reference is a searchable cheat sheet covering the Web Accessibility Initiative Accessible Rich Internet Applications (WAI-ARIA) specification across four categories: Widgets (13 interactive role examples including alert, button, checkbox, dialog, grid, link, menu/menuitem, progressbar, radio, slider, tab/tabpanel, textbox, and tooltip), Structure (heading with aria-level, list/listitem, and tree/treeitem), Landmarks (banner, navigation, main, search, complementary), and States/Properties (aria-checked, aria-disabled, aria-expanded, aria-hidden, aria-label, aria-live, aria-selected, aria-required).
This reference is designed for front-end developers, UX engineers, and accessibility specialists who build inclusive web applications. ARIA attributes are essential when native HTML semantics are insufficient — for example, when a custom div-based dropdown needs role="combobox" and aria-expanded, or when a single-page application needs role="alert" and aria-live="polite" to announce dynamic content updates to screen reader users. Each entry shows the correct HTML usage with real-world code examples.
WAI-ARIA compliance is required for WCAG 2.1 Level AA accessibility standards, which are legally mandated in many jurisdictions and essential for users of assistive technologies like screen readers (NVDA, JAWS, VoiceOver). The four categories map to the ARIA specification structure: interactive components need widget roles, page regions need landmark roles, document structure needs structural roles, and current states need ARIA properties. All content is browser-based, free, and includes dark mode.
Key Features
- Widget roles: alert (auto-announced), button, checkbox, dialog (modal with aria-modal), grid, link, menu/menuitem, progressbar, radio, slider, tab/tabpanel/tablist, textbox, tooltip
- Landmark roles: banner (page header), navigation (with aria-label), main (primary content), search (search region), complementary (aside content)
- Structure roles: heading (with required aria-level), list/listitem for custom lists, tree/treeitem for hierarchical components
- ARIA states: aria-checked (true/false/mixed), aria-disabled, aria-expanded, aria-hidden (decorative elements), aria-selected
- ARIA properties: aria-label (direct label), aria-live (polite/assertive for dynamic updates), aria-required (form fields)
- Role + state combinations: e.g., role="tab" with aria-selected, role="button" with aria-expanded and aria-controls
- HTML examples with proper tabindex usage for keyboard navigation on non-interactive elements
- Live region patterns: aria-live="polite" for search results, role="alert" for error messages and status updates
Frequently Asked Questions
What is WAI-ARIA and when should I use it?
WAI-ARIA (Web Accessibility Initiative Accessible Rich Internet Applications) is a W3C specification that provides semantic attributes for HTML elements that lack native accessibility semantics. Use ARIA when building custom interactive widgets (carousels, date pickers, custom dropdowns) that cannot be implemented with native HTML elements like <button>, <select>, or <input>. The first rule of ARIA: if you can use a native HTML element with the correct semantics, do so instead.
What is the difference between aria-label and a visible label?
A visible label (associated with <label for="..."> or wrapping the input) is the preferred approach — it is visible to all users and automatically read by screen readers. aria-label is used when a visible label is not possible or desirable, such as icon buttons that only show a graphic. The aria-label value replaces the element's accessible name entirely, so use aria-labelledby instead if you want to reference an existing visible text element.
When should I use role="alert" versus aria-live="polite"?
role="alert" (equivalent to aria-live="assertive") interrupts the user and reads immediately — use it for critical errors and important warnings that need immediate attention. aria-live="polite" waits for the user to finish current activity before announcing — use it for search result counts, status messages, and non-critical updates. Both work with dynamically injected content in single-page applications.
How do I make a custom modal dialog accessible?
Apply role="dialog" with aria-modal="true" to the container, use aria-labelledby pointing to the dialog's heading element. When the dialog opens, move keyboard focus to the first focusable element inside and implement a focus trap (Tab and Shift+Tab cycle only within the dialog). When the dialog closes, return focus to the element that triggered it. Add a close button with aria-label="Close dialog".
What is the difference between aria-expanded and aria-selected?
aria-expanded indicates whether a collapsible element (accordion, dropdown, tree node) is open (true) or closed (false). It is paired with aria-controls pointing to the controlled region. aria-selected indicates which option is currently selected in a multi-item widget like a tablist, listbox, or grid. Unlike checked state, selected state does not toggle — it shows which item is active.
How do I implement an accessible tab interface?
Use a div with role="tablist" containing buttons with role="tab" and aria-selected="true/false". Each tab button should have aria-controls pointing to its corresponding tabpanel div. The active tab has aria-selected="true"; inactive tabs have aria-selected="false". Implement keyboard navigation: Left/Right arrows move between tabs, Home/End jump to first/last, Tab moves into the active tabpanel.
When do I need to add tabindex to an element?
Add tabindex="0" to make a non-interactive element (div, span) focusable and include it in the natural tab order — required when you assign an interactive ARIA role like role="button", role="checkbox", or role="slider" to a non-native element. Use tabindex="-1" to make an element programmatically focusable (via JavaScript focus()) but not reachable via keyboard Tab navigation. Avoid positive tabindex values as they disrupt natural reading order.
What does aria-hidden do and when should I use it?
aria-hidden="true" removes an element and all its children from the accessibility tree, making them invisible to screen readers. Use it for purely decorative elements (icon fonts, background images, duplicate text), UI chrome that would be confusing to announce (loading spinners adjacent to labeled buttons), and off-screen content that is not logically visible. Never apply aria-hidden to an element that has or contains keyboard focus.