advanced

ARIA

Apply ARIA roles, states, and properties only when native HTML is insufficient and the widget behavior matches the announced semantics.

ARIA (Accessible Rich Internet Applications) adds roles, states, and properties when native HTML cannot express the widget. **First rule of ARIA: do not use ARIA if native HTML works.** ARIA describes; it does not implement keyboard behavior, focus, or event handling.

					<!-- Prefer native -->
<select>...</select>

<!-- Custom listbox needs role, keyboard, and state -->
<ul role="listbox" aria-activedescendant="opt-2">
  <li id="opt-1" role="option">One</li>
  <li id="opt-2" role="option" aria-selected="true">Two</li>
</ul>
				

| Mistake | Fix | |---------|-----| | `role="button"` on div without keys | Use `<button>` or implement Space/Enter | | Wrong role for behavior | Match APG pattern for tabs, combobox, dialog | | `aria-hidden` on focused child | Breaks focus and announcements |

Use WAI-ARIA Authoring Practices patterns for complex widgets; pair with tests, not only attributes.

On interviews: role vs native element; `aria-expanded`, `aria-controls`, `aria-activedescendant`; why `aria-label` overrides visible text.

Common pitfalls: sprinkling roles without behavior; redundant ARIA on native elements; live region spam; incorrect menu vs listbox roles.

The trade-off is shipping custom UI faster versus owning full accessibility behavior.

Checklist:

  • Native HTML first; ARIA only when necessary.
  • Implement full keyboard and focus for custom roles.
  • Follow APG for composite widgets.
  • Validate with accessibility tree inspection, not only ESLint plugins.