--- name: aria-patterns description: Provides ARIA roles, states, and properties for interactive components. Use when building custom widgets, fixing screen reader issues, or implementing modals, tabs, accordions, menus, or dialogs accessibly. --- # ARIA Patterns Guide ## Overview Implement accessible interactive components using correct ARIA roles, states, and properties. Provides copy-paste patterns for common widgets that work with screen readers and keyboard navigation. ## When to Use - Building custom interactive components - Making dynamic content accessible - Fixing screen reader issues - Adding keyboard support to custom widgets ## Quick Reference: First Rules of ARIA 1. **Don't use ARIA if native HTML works** - ` ``` **Custom (when necessary):** ```html
Toggle
``` ### Toggle Button ```html ``` --- ### Modal Dialog ```html
``` **Required behavior:** - Focus moves to dialog on open - Focus trapped within dialog - Escape key closes dialog - Focus returns to trigger on close ```js // Focus trap example function trapFocus(dialog) { const focusable = dialog.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); const first = focusable[0]; const last = focusable[focusable.length - 1]; dialog.addEventListener('keydown', (e) => { if (e.key === 'Tab') { if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); } else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); } } }); } ``` --- ### Dropdown Menu ```html ``` **Keyboard:** - Enter/Space: Open menu, activate item - Arrow Down: Next item (or first if closed) - Arrow Up: Previous item - Escape: Close menu - Home: First item - End: Last item --- ### Tabs ```html
Profile content...
``` **Keyboard:** - Arrow Left/Right: Move between tabs - Home: First tab - End: Last tab - Tab: Move into panel content --- ### Accordion ```html

Section 1 content...

``` --- ### Tooltip ```html ``` **Note:** For interactive content, use a disclosure or dialog instead. --- ### Alert / Status Messages ```html
Error: Please enter a valid email address.
3 items in cart
``` --- ### Combobox (Autocomplete) ```html
``` **Update `aria-activedescendant` to the ID of the highlighted option.** --- ### Progress / Loading ```html
75%
Loading...
``` --- ## Common ARIA Attributes | Attribute | Purpose | Example | |-----------|---------|---------| | `aria-label` | Accessible name | `aria-label="Close"` | | `aria-labelledby` | Name from element | `aria-labelledby="heading-1"` | | `aria-describedby` | Description | `aria-describedby="hint-1"` | | `aria-expanded` | Open/closed state | `aria-expanded="true"` | | `aria-controls` | Controlled element | `aria-controls="menu-1"` | | `aria-hidden` | Hide from AT | `aria-hidden="true"` | | `aria-live` | Announce updates | `aria-live="polite"` | | `aria-pressed` | Toggle state | `aria-pressed="false"` | | `aria-selected` | Selection state | `aria-selected="true"` | | `aria-current` | Current item | `aria-current="page"` | ## Screen Reader Only Text ```css .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } ``` ## Testing 1. **Keyboard only**: Tab through, use arrows, Enter, Escape 2. **Screen reader**: Test with VoiceOver (Mac), NVDA (Windows), or JAWS 3. **Check announcements**: Are labels, states, and changes announced? 4. **axe DevTools**: Run automated accessibility audit