Vue Accessibility Skill
Target: WCAG 2.2 AA. Priority order: semantic HTML > keyboard support > focus management > ARIA. ARIA is the last resort, not the first tool —
<button>beats<div role="button" tabindex="0">plus three handlers.
Non-negotiables for every component
- Interactive = focusable + keyboard-operable (
<button>,<a href>,<input>give this free). - Every input has a
<label>; every image analt(emptyalt=""for decorative). - Visible focus indicator — never
outline: nonewithout a replacement (:focus-visible). - Click targets ≥ 24×24px; color is never the only signal.
- State changes announce themselves: errors, async results, route changes (live regions / focus moves).
SPA-specific traps (Vue)
| Trap | Fix |
|---|---|
| Route change is silent to screen readers | Announce + move focus — focus-management |
| Modal via Teleport, focus escapes behind it | Focus trap + inert/aria-modal — focus-management |
v-if swaps content without announcement |
aria-live region or focus the new content |
Custom <div> dropdown/tab/menu widgets |
Use the ARIA pattern — aria-components |
| Validation errors only shown as red text | aria-describedby + aria-invalid wiring — see vue-forms skill + aria-components |
Reference Map
| Topic | Description | Path |
|---|---|---|
| ARIA components | Modal, tabs, menu, combobox, disclosure, toast patterns in Vue | aria-components |
| Focus management | Teleport modals, focus traps, route announcements, skip links | focus-management |
| Testing | vitest-axe, Playwright audits, eslint-plugin-vuejs-accessibility | testing-a11y |