Accessibility
Build interfaces that work for everyone. Accessibility is a technical requirement, not an afterthought. WCAG 2.2 AA is the professional baseline.
Inaccessible interfaces exclude users and create legal liability. WCAG 2.2 Level AA is the professional baseline.
In brief:
- Semantic HTML first — never ARIA where native elements work
- Every mouse action needs a keyboard equivalent
- Colour contrast: 4.5:1 (text), 3:1 (large text/UI components)
- Automated tools catch ~30-40% of issues — manual keyboard/screen reader testing is essential
WCAG Principles (POUR)
| Principle | Key requirements |
|---|---|
| Perceivable | Alt text, captions, sufficient colour contrast, no colour-alone cues |
| Operable | Full keyboard accessibility, no keyboard traps, skip navigation, sufficient time |
| Understandable | Clear language, consistent navigation, error identification and suggestions |
| Robust | Valid HTML, correct ARIA, name/role/value for all UI components |
WCAG 2.2 added: focus appearance (2.4.11), dragging movements (2.5.7), target size minimum (2.5.8). Review if upgrading from 2.1.
Semantic HTML
Native HTML has built-in accessibility — keyboard behaviour, ARIA roles, screen reader announcements. <div onClick> throws it all away.
Keyboard Navigation
Every mouse action must have a keyboard equivalent. Many users depend entirely on keyboard — power users, motor disabilities, switch access devices.
| Key | Expected behaviour |
|---|---|
| Tab | Move focus to the next focusable element in DOM order |
| Shift + Tab | Move focus to the previous focusable element |
| Enter | Activate a button or link; submit a form |
| Space | Toggle a checkbox; activate a button |
| Arrow keys | Navigate within a composite widget: menu items, tabs, radio groups, listboxes |
| Escape | Close a modal, popover, or dropdown; cancel an operation |
| Home / End | Move to the first or last item in a list or menu |
ARIA Usage
ARIA communicates semantics to assistive technologies when native HTML can't. First rule: no ARIA where native HTML works. Incorrect ARIA is worse than none — it actively misleads.
Common ARIA patterns
Never use aria-hidden="true" on a focusable element. This hides it from screen readers while still allowing keyboard focus, creating a confusing experience. Remove the element from the tab order with tabIndex={-1} or hide it completely with display: none.
Colour and Contrast
| Element | AA (minimum) | AAA (enhanced) |
|---|---|---|
| Normal text (< 18px) | 4.5:1 | 7:1 |
| Large text (≥ 18px or ≥ 14px bold) | 3:1 | 4.5:1 |
| UI components, focus indicators | 3:1 against adjacent | — |
| Disabled components | No requirement | — |
- Never rely on colour alone — pair with text, pattern, or shape
- Use browser DevTools contrast checker during design
- Test in both light and dark modes
- Focus indicators must meet 3:1 against background
Focus Management
When the DOM changes dynamically — modals, section updates, content loads — programmatically manage focus so keyboard users aren't stranded.
Testing for Accessibility
Automated tools catch ~30–40% of WCAG issues. The rest requires manual keyboard and screen reader testing. Both are necessary.
| Method | What it catches | Tool |
|---|---|---|
| Automated linting | Missing alt text, incorrect ARIA roles, form label associations | eslint-plugin-jsx-a11y |
| Automated runtime | Contrast failures, ARIA violations in rendered output | axe-core via @axe-core/react or vitest-axe |
| Keyboard testing | Focus order, keyboard traps, missing focus indicators, ARIA keyboard patterns | Manual — keyboard only, no mouse |
| Screen reader testing | Announced content, heading structure, live regions, form instructions | VoiceOver (macOS/iOS), NVDA (Windows), JAWS (Windows) |
| Zoom testing | Layout reflow at 200%, 400% zoom; text does not overflow containers | Browser zoom — 200% and 400% |
AI agents perform preliminary accessibility audits: provide component source, ask for WCAG 2.2 AA review. Agents catch missing ARIA, heading hierarchy, contrast, keyboard gaps — but don't replace axe-core in CI or manual screen reader testing.
Testing Strategy
Build confidence through a layered testing strategy: unit tests for logic, integration tests for component contracts, and end-to-end tests for critical user paths.
Animation & Motion
Use animation intentionally — CSS transitions, keyframe animations, Framer Motion, gesture handling, page transitions, and reduced motion support.