Design Engineering
Quality & Polish

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)

PrincipleKey requirements
PerceivableAlt text, captions, sufficient colour contrast, no colour-alone cues
OperableFull keyboard accessibility, no keyboard traps, skip navigation, sufficient time
UnderstandableClear language, consistent navigation, error identification and suggestions
RobustValid 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.

KeyExpected behaviour
TabMove focus to the next focusable element in DOM order
Shift + TabMove focus to the previous focusable element
EnterActivate a button or link; submit a form
SpaceToggle a checkbox; activate a button
Arrow keysNavigate within a composite widget: menu items, tabs, radio groups, listboxes
EscapeClose a modal, popover, or dropdown; cancel an operation
Home / EndMove 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

ElementAA (minimum)AAA (enhanced)
Normal text (< 18px)4.5:17:1
Large text (≥ 18px or ≥ 14px bold)3:14.5:1
UI components, focus indicators3:1 against adjacent
Disabled componentsNo 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.

MethodWhat it catchesTool
Automated lintingMissing alt text, incorrect ARIA roles, form label associationseslint-plugin-jsx-a11y
Automated runtimeContrast failures, ARIA violations in rendered outputaxe-core via @axe-core/react or vitest-axe
Keyboard testingFocus order, keyboard traps, missing focus indicators, ARIA keyboard patternsManual — keyboard only, no mouse
Screen reader testingAnnounced content, heading structure, live regions, form instructionsVoiceOver (macOS/iOS), NVDA (Windows), JAWS (Windows)
Zoom testingLayout reflow at 200%, 400% zoom; text does not overflow containersBrowser 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.

On this page