Accessibility
Overview
WCAG 2.1 AA compliance for React + shadcn/ui — keyboard navigation, screen readers, color contrast, semantic HTML.
When to Use
- Building any new UI component or page
- Before production launch
- When accessibility audit fails
- When adding forms, modals, or interactive elements
Workflow
Phase 1: Semantic HTML
- Correct heading hierarchy (h1 > h2 > h3, one h1/page)
- Landmarks:
<nav>,<main>,<aside>,<section> <button>for actions,<a>for navigation (never<div onClick>)<label>for all form inputs
Phase 2: Keyboard
- All interactive elements focusable via Tab
- Visible focus indicators (shadcn
focus-visiblering) - Escape closes modals/dropdowns
- Arrow keys in menus/tabs
- Test: navigate entire page with keyboard only
Phase 3: Screen Readers
aria-labelon icon-only buttons:<Button variant="ghost" size="icon" aria-label="Close dialog"> <X className="h-4 w-4" /> </Button>aria-live="polite"on dynamic regions (toasts, loading)role="alert"on error messagesaria-hidden="true"on decorative elements
Phase 4: Color & Contrast
- Text contrast: 4.5:1 minimum (AA)
- Large text (18px+): 3:1 minimum
- Never color alone to convey meaning (add icons/text)
- Test: DevTools > Rendering > Emulate vision deficiencies
Phase 5: Forms
- Visible labels on every input
aria-required="true"on required fields- Errors linked with
aria-describedby+aria-invalid="true"
Phase 6: Audit
- Lighthouse Accessibility > 90
- axe DevTools extension
- Keyboard-only walkthrough
- 200% zoom — layout intact
Checklist
- Semantic landmarks and heading hierarchy
- All elements keyboard-accessible
- Visible focus indicators
-
aria-labelon icon buttons -
aria-liveon dynamic content - 4.5:1 contrast ratios
- Color not sole indicator
- Form labels and error linking
- Lighthouse Accessibility > 90
- Tested keyboard-only + 200% zoom