Freebie

ARIA attributes

Accessible Rich Internet Applications (ARIA) is a set of HTML attributes that communicate the role, state, and properties of user interface elements to assistive technologies. Before reaching for ARIA, always check whether a native HTML element already conveys the same meaning. A <button> is always preferable to <div role="button">, and a <nav> is always preferable to <div role="navigation">.

Rules of ARIA use

The W3C defines five rules for ARIA. Apply them in order:

  1. Do not add ARIA if a native HTML element or attribute already provides the semantics or behavior you need. For example, apply <button> instead of <div role="button">. Native elements carry built-in keyboard support, focus management, and screen reader announcements that ARIA cannot fully replicate.

  2. Do not change native semantics unless you have no other option. For example, do not add role="heading" to a <button>. If you need a heading, apply the appropriate <h1> through <h6> element.

  3. All interactive ARIA controls must be keyboard accessible. If you create a custom widget with a role like slider or menu, keyboard users must be able to operate it without a mouse. This means handling keydown and keyup events in addition to click.

  4. Do not apply role="presentation" or aria-hidden="true" to a focusable element. Hiding a focusable element from the accessibility tree while leaving it in the tab order creates a broken experience. For example, a close button hidden with aria-hidden="true" is still reachable by keyboard, but the screen reader announces nothing when the button receives focus.

  5. All interactive elements must have an accessible name. An icon button with no visible label must still provide a name through aria-label, aria-labelledby, or visible text content.

For the full specification, see the W3C notes on ARIA use.

Cheatsheet

The following table lists common ARIA attributes, what they communicate, and when to apply them:

ARIA AttributeDescriptionUse CaseExample Snippet
aria-labelProvides an accessible label for an elementWhen no visible label is available<button aria-label="Close"></button>
aria-labelledbyReferences another element that labels this oneFor complex widgets or grouped labels<div aria-labelledby="section-title">
aria-describedbyReferences text that describes the elementAdd supplemental description<input aria-describedby="hint">
aria-hiddenHides an element from assistive techHide decorative elements<span aria-hidden="true">★</span>
aria-expandedIndicates whether a section or control is expandedToggle sections like accordions or menus<button aria-expanded="false">Menu</button>
aria-pressedIndicates the pressed state of a toggle buttonToggle buttons<button aria-pressed="false">Bold</button>
aria-checkedIndicates the checked state of a checkbox/radioCustom checkbox widgets<div role="checkbox" aria-checked="true"></div>
aria-selectedIndicates the selected state of an item in a setTabs, selectable lists<li aria-selected="true">Tab 1</li>
aria-disabledMarks an element as disabled (not interactive)Disable elements not using native disabled<div aria-disabled="true">Save</div>
aria-controlsReferences the element that is controlledButton controlling a menu or dialog<button aria-controls="menu1">Open Menu</button>
aria-liveAnnounces content changes dynamicallyAlerts, chat updates<div aria-live="polite">New message</div>
roleDefines the role of an elementMarkup custom widgets or landmarks<div role="dialog">...</div>
aria-currentIndicates the current item within a setCurrent page in nav<a aria-current="page" href="/about">About</a>
aria-modalIndicates whether a dialog is modalAccessibility for modals<div role="dialog" aria-modal="true">
aria-busySignals loading stateFor areas loading content<div aria-busy="true">Loading...</div>
aria-haspopupIndicates the element has a popup (like a menu, dialog, listbox, etc.)Use with buttons or links that trigger menus or popups<button aria-haspopup="menu" aria-controls="dropdown">Options</button>