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.
← Back to Client Side| Region | Law / Standard | What it requires |
|---|---|---|
| EU | European Accessibility Act (in force June 2025) | Most consumer-facing digital products must meet WCAG 2.1 AA. |
| US | ADA, Section 508 | Public sector and "places of public accommodation" — courts cite WCAG 2.1 AA in practice. |
| UK | Equality Act, PSBAR | Public sector bodies must publish an accessibility statement. |
| Canada | ACA, AODA (Ontario) | Federal & Ontario regulations citing WCAG. |
| Global | WCAG 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.
Users can sense the content. Alt text on images, captions on video, sufficient contrast, no info conveyed by color alone.
Users can drive the UI. Keyboard support, no keyboard traps, enough time, no seizure-triggering motion.
Content & behavior are predictable. Clear labels, consistent navigation, helpful error messages.
Works across browsers and assistive tech. Valid HTML, correct semantics, ARIA where needed.
<button>, not <div onclick>. You get keyboard, focus, and screen-reader behavior for free.<a href> for navigation, <button> for actions. Don't mix them up.<label> tied to every <input>. Placeholders are not labels.h1 → h2 → h3. Screen-reader users navigate by heading.<header>, <nav>, <main>, <footer>.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.
outline: none without a replacement style.prefers-reduced-motion for animations.prefers-color-scheme for dark mode.<label>.aria-live) and tied to the field via aria-describedby.<fieldset> + <legend>.type (email, tel, date) and autocomplete tokens.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.
| Tool | Type | What it catches |
|---|---|---|
| axe-core / @axe-core/react | Runtime + CI | The de-facto a11y engine — used by Lighthouse, Cypress, Playwright. |
| eslint-plugin-jsx-a11y | Lint | Catches obvious React issues at edit time (missing alt, no-onclick-on-div). |
| Lighthouse | Audit | Built into Chrome DevTools — runs axe + best practices. |
| Pa11y, WAVE | Audit | CLI / browser audits for whole-page scans. |
| Storybook a11y addon | Component | Per-story axe runs; great for design systems. |
| NVDA / VoiceOver / TalkBack | Manual | The actual screen readers. Free. Use them. |
| Accessibility Insights | Audit | Microsoft'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.
Add eslint-plugin-jsx-a11y + axe in CI on day one. Pick a component library that takes a11y seriously (Radix, React Aria, Headless UI).
Run Lighthouse / axe to triage. Fix the highest-traffic flows first — sign-in, checkout, search.
Build accessible primitives once (Button, Modal, Combobox) and the rest of the app inherits it.
EAA compliance is binding from June 2025. Get a third-party audit and publish an accessibility statement.
<div onclick> everywhere. No keyboard, no role, no name.