Client-Side Tooling · 7 of 8

Accessibility (a11y)

Building interfaces that everyone can use — including people who navigate with a keyboard, a screen reader, voice control, magnification, or in bright sunlight on a phone. Increasingly a legal requirement, not a nice-to-have.

WCAGARIAScreen readersKeyboardContrastaxe
← Back to Client Side
Quick Facts

At a Glance

Basic Concepts

  • a11y is shorthand for accessibility — 11 letters between the a and the y.
  • WCAG (Web Content Accessibility Guidelines) is the global standard. WCAG 2.2 AA is what most laws and contracts require.
  • Screen readers (NVDA, JAWS, VoiceOver, TalkBack) read the page aloud — they need correct semantics, not just visuals.
  • Keyboard navigation means every interactive element is reachable and usable with Tab, Shift+Tab, Enter, Space, and arrows — no mouse required.
  • ARIA attributes patch semantics onto custom widgets. Rule #1: don't use ARIA if a native HTML element does the job.
Why It Matters

Audience & Law

RegionLaw / StandardWhat it requires
EUEuropean Accessibility Act (in force June 2025)Most consumer-facing digital products must meet WCAG 2.1 AA.
USADA, Section 508Public sector and "places of public accommodation" — courts cite WCAG 2.1 AA in practice.
UKEquality Act, PSBARPublic sector bodies must publish an accessibility statement.
CanadaACA, AODA (Ontario)Federal & Ontario regulations citing WCAG.
GlobalWCAG 2.2 (2023)The reference standard. WCAG 3.0 is in draft.

Roughly 1 in 6 people live with a disability that affects how they use software. Even if you ignore the law, that's a sixth of your users.

The Four Principles

POUR (WCAG)

Perceivable

Users can sense the content. Alt text on images, captions on video, sufficient contrast, no info conveyed by color alone.

Operable

Users can drive the UI. Keyboard support, no keyboard traps, enough time, no seizure-triggering motion.

Understandable

Content & behavior are predictable. Clear labels, consistent navigation, helpful error messages.

Robust

Works across browsers and assistive tech. Valid HTML, correct semantics, ARIA where needed.

Mechanics

How a11y Actually Works

Semantic HTML — Do This First
  • Use <button>, not <div onclick>. You get keyboard, focus, and screen-reader behavior for free.
  • Use <a href> for navigation, <button> for actions. Don't mix them up.
  • Use <label> tied to every <input>. Placeholders are not labels.
  • Use heading levels in order — h1h2h3. Screen-reader users navigate by heading.
  • Use landmarks: <header>, <nav>, <main>, <footer>.
ARIA — When HTML Isn't Enough

ARIA (Accessible Rich Internet Applications) attributes describe role, state, and properties of custom widgets to assistive tech.

  • role="dialog", aria-modal="true" — for modals.
  • aria-label, aria-labelledby — naming an element.
  • aria-expanded, aria-controls — disclosure widgets, menus.
  • aria-live="polite" — announce dynamic updates (toasts, search results).
  • aria-hidden="true" — hide decorative content from screen readers.

The first rule of ARIA: don't use ARIA. Use a native HTML element if one exists. Wrong ARIA is worse than no ARIA.

Keyboard Navigation
  • Every interactive element must be reachable with Tab.
  • Focus order should match visual order.
  • Focus must be visible — never outline: none without a replacement style.
  • Modals must trap focus while open and return it on close.
  • Provide a "Skip to content" link as the first focusable element.
  • Arrow keys for components like menus, tabs, radio groups, listboxes (per ARIA Authoring Practices).
Color & Contrast
  • Body text needs 4.5:1 contrast (WCAG AA); large text 3:1.
  • Don't use color alone to convey meaning — pair with icons, text, or shape.
  • Test with Windows High Contrast / forced-colors mode — no hard-coded backgrounds.
  • Honor prefers-reduced-motion for animations.
  • Honor prefers-color-scheme for dark mode.
Forms — The Highest-Stakes UI
  • Every input has a visible <label>.
  • Errors are announced (aria-live) and tied to the field via aria-describedby.
  • Group related fields with <fieldset> + <legend>.
  • Use the right type (email, tel, date) and autocomplete tokens.
  • Don't time out forms aggressively; warn before clearing data.
The Accessibility Tree

Browsers expose a parallel tree to assistive tech — derived from the DOM but with computed roles, names, and states. Inspect it in Chrome/Firefox DevTools' Accessibility panel. If a control has no name in that tree, screen readers see "button" with no context.

Tooling

Testing & Linting

ToolTypeWhat it catches
axe-core / @axe-core/reactRuntime + CIThe de-facto a11y engine — used by Lighthouse, Cypress, Playwright.
eslint-plugin-jsx-a11yLintCatches obvious React issues at edit time (missing alt, no-onclick-on-div).
LighthouseAuditBuilt into Chrome DevTools — runs axe + best practices.
Pa11y, WAVEAuditCLI / browser audits for whole-page scans.
Storybook a11y addonComponentPer-story axe runs; great for design systems.
NVDA / VoiceOver / TalkBackManualThe actual screen readers. Free. Use them.
Accessibility InsightsAuditMicrosoft's guided assessment — covers what automation can't.

Automated tools catch about 30–40% of issues. The rest needs keyboard testing, screen-reader testing, and human judgment.

Picking

Where to Start

New project

Add eslint-plugin-jsx-a11y + axe in CI on day one. Pick a component library that takes a11y seriously (Radix, React Aria, Headless UI).

Existing app

Run Lighthouse / axe to triage. Fix the highest-traffic flows first — sign-in, checkout, search.

Design system

Build accessible primitives once (Button, Modal, Combobox) and the rest of the app inherits it.

Going to market in EU

EAA compliance is binding from June 2025. Get a third-party audit and publish an accessibility statement.

Pitfalls

Common Anti-Patterns

  • Div soup<div onclick> everywhere. No keyboard, no role, no name.
  • Placeholder-as-label — vanishes on focus, low contrast, lost on autofill.
  • Removing focus outlines for "design reasons" without replacement.
  • Custom dropdowns that ignore arrow-key conventions and don't manage focus.
  • Inaccessible modals — no focus trap, focus doesn't return on close.
  • Auto-playing video / motion with no pause control.
  • Color-only state (red = error) — invisible to colorblind users.
  • "Click here" links — meaningless out of context for screen-reader users.
Continue

Other Client-Side Tooling