7 min read
On this page

Accessibility

Why Accessibility Matters

Accessibility (a11y) ensures that products are usable by people with the widest range of abilities, in the widest range of situations. Approximately 15-20% of the global population has some form of disability.

Accessibility is not a feature --- it is a quality of the design. It benefits everyone:

  • Permanent disability: Blind, deaf, motor impairment
  • Temporary disability: Broken arm, ear infection, migraine
  • Situational disability: Bright sunlight, noisy environment, holding a child

WCAG: Web Content Accessibility Guidelines

WCAG is the international standard (W3C) for web accessibility. Current versions: WCAG 2.1 (2018) and WCAG 2.2 (2023).

The POUR Principles

All WCAG guidelines fall under four principles:

1. Perceivable

Information and UI components must be presentable in ways users can perceive.

| Guideline | Requirement | |-----------|------------| | Text alternatives | Alt text for all non-decorative images | | Time-based media | Captions for video, transcripts for audio | | Adaptable | Content can be presented in different ways without losing information | | Distinguishable | Sufficient color contrast, resizable text, no audio auto-play |

2. Operable

UI components and navigation must be operable by all users.

| Guideline | Requirement | |-----------|------------| | Keyboard accessible | All functionality available via keyboard | | Enough time | Users can extend or disable time limits | | Seizures | No content flashing more than 3 times per second | | Navigable | Skip links, page titles, focus order, link purpose clear | | Input modalities (2.1) | Pointer gestures have alternatives, motion actuation optional | | Dragging (2.2) | Drag operations have single-pointer alternative | | Target size (2.2) | Minimum 24x24 CSS pixels (AA) |

3. Understandable

Information and UI operation must be understandable.

| Guideline | Requirement | |-----------|------------| | Readable | Language of page declared, abbreviations explained | | Predictable | Consistent navigation, no unexpected context changes | | Input assistance | Error identification, labels, error prevention | | Consistent help (2.2) | Help mechanisms appear in same relative location |

4. Robust

Content must be robust enough to be interpreted by a wide variety of user agents, including assistive technologies.

| Guideline | Requirement | |-----------|------------| | Compatible | Valid markup, name/role/value programmatically determined | | Status messages | Conveyed to assistive tech without receiving focus |

Conformance Levels

| Level | Meaning | Example | |-------|---------|---------| | A | Minimum accessibility | Alt text on images, keyboard access | | AA | Standard target for most organizations | 4.5:1 contrast, visible focus indicators | | AAA | Enhanced accessibility | 7:1 contrast, sign language for video |

Most legal requirements and organizational standards target Level AA.


ARIA (Accessible Rich Internet Applications)

ARIA attributes add semantic information to HTML elements for assistive technologies.

Core ARIA Concepts

<!-- Roles: what the element IS -->
<div role="button">Click me</div>
<div role="alert">Error: invalid email</div>
<nav role="navigation" aria-label="Main">...</nav>

<!-- States: current condition of the element -->
<button aria-expanded="false">Menu</button>
<input aria-invalid="true">

<!-- Properties: characteristics of the element -->
<input aria-label="Search" type="text">
<div aria-describedby="help-text">...</div>
<div aria-live="polite">3 new messages</div>

ARIA Rules

  1. Do not use ARIA if native HTML works. <button> is better than <div role="button">.
  2. Do not change native semantics unless necessary.
  3. All interactive ARIA controls must be keyboard accessible.
  4. Do not use role="presentation" or aria-hidden="true" on focusable elements.
  5. All interactive elements must have an accessible name.

Live Regions

Announce dynamic content changes to screen readers:

<!-- polite: announced at next pause -->
<div aria-live="polite">Cart updated: 3 items</div>

<!-- assertive: announced immediately, interrupts -->
<div aria-live="assertive">Session expiring in 60 seconds</div>

<!-- Specialized live region roles -->
<div role="alert">Error: password too short</div>  <!-- implicitly assertive -->
<div role="status">File uploaded successfully</div> <!-- implicitly polite -->

Screen Readers

Screen readers convert on-screen content to speech or Braille output.

| Screen Reader | Platform | Cost | |---------------|----------|------| | NVDA | Windows | Free (open source) | | JAWS | Windows | Commercial | | VoiceOver | macOS, iOS | Built-in | | TalkBack | Android | Built-in | | Narrator | Windows | Built-in | | Orca | Linux | Free (open source) |

How Screen Readers Navigate

  • Heading navigation (H key): Jump between headings. Proper heading hierarchy (h1 > h2 > h3) is essential.
  • Landmark navigation: Jump between <nav>, <main>, <aside>, <footer>.
  • Tab key: Move between interactive elements (links, buttons, form fields).
  • Screen reader cursor: Arrow keys to read content linearly.
  • Forms mode: Interact with form controls.

Writing for Screen Readers

<!-- Image alt text -->
<img src="chart.png" alt="Bar chart showing Q3 revenue up 15% from Q2">
<img src="decorative-line.png" alt="">  <!-- decorative: empty alt -->

<!-- Link text -->
BAD:  <a href="...">Click here</a>
GOOD: <a href="...">Download 2025 annual report (PDF, 2.4MB)</a>

<!-- Form labels -->
BAD:  <input type="email">
GOOD: <label for="email">Email address</label>
      <input type="email" id="email" autocomplete="email">

Keyboard Navigation

All interactive functionality must be accessible via keyboard alone.

Essential Keyboard Patterns

| Key | Expected Behavior | |-----|-------------------| | Tab | Move focus to next interactive element | | Shift+Tab | Move focus to previous interactive element | | Enter | Activate buttons, follow links | | Space | Activate buttons, toggle checkboxes | | Arrow keys | Navigate within widgets (tabs, menus, radio groups) | | Escape | Close modals, dismiss popups, cancel | | Home/End | First/last item in a list or menu |

Focus Management

/* Never do this without replacement: */
*:focus { outline: none; }  /* DESTROYS keyboard accessibility */

/* Instead, provide visible focus indicators: */
:focus-visible {
    outline: 3px solid #2563EB;
    outline-offset: 2px;
}

Focus trapping: Modal dialogs must trap focus within the dialog. Tab should cycle through dialog elements only, not reach the page behind.

Focus restoration: When a modal closes, return focus to the element that triggered it.


Color and Contrast

Contrast Requirements (WCAG 2.1)

| Element | AA Ratio | AAA Ratio | |---------|----------|-----------| | Normal text (< 18pt) | 4.5:1 | 7:1 | | Large text (>= 18pt or >= 14pt bold) | 3:1 | 4.5:1 | | UI components and graphical objects | 3:1 | Not defined |

Color Independence

Never convey information through color alone:

Form validation:
  BAD:  Red border on error fields (color only)
  GOOD: Red border + error icon + error message text

Data visualization:
  BAD:  Red line vs green line (indistinguishable for color-blind users)
  GOOD: Red dashed line vs green solid line + labeled legend

Captions and Transcripts

| Media Type | Required (AA) | Format | |------------|---------------|--------| | Pre-recorded video with audio | Captions | WebVTT, SRT | | Pre-recorded audio only | Transcript | HTML text | | Live video with audio | Live captions | Real-time captioning | | Pre-recorded video only | Audio description OR text alternative | Narration track |

Caption quality: Captions should include speaker identification, sound effects [door slams], and music descriptions [upbeat jazz].


Cognitive Accessibility

Design for users with cognitive and learning disabilities (dyslexia, ADHD, autism, intellectual disabilities, acquired brain injuries).

  • Clear language: Short sentences, common words, avoid jargon
  • Consistent navigation: Same layout and patterns across pages
  • Error recovery: Clear error messages, undo capability, confirmation for destructive actions
  • Predictable behavior: No unexpected changes, no auto-advancing content
  • Chunked content: Break information into small, manageable pieces
  • Multiple formats: Support text, images, audio, and video for the same content
  • Minimal distractions: Allow users to hide non-essential content, reduce motion

Motor Accessibility

Design for users with limited motor control (tremors, paralysis, repetitive strain, missing limbs).

  • Large touch targets: Minimum 44x44px (Apple) / 48x48dp (Android) / 24x24 CSS px (WCAG 2.2 AA)
  • Adequate spacing: Prevent accidental activation of adjacent targets
  • No complex gestures required: Multi-finger gestures need single-pointer alternatives
  • No time-dependent actions: Allow users to extend or remove time limits
  • Switch access: Support for single-switch and sip-and-puff devices
  • Voice control: Ensure visible labels match accessible names

Assistive Technologies

| Technology | Users | Design Consideration | |------------|-------|---------------------| | Screen reader | Blind, low vision | Semantic HTML, alt text, ARIA | | Screen magnifier | Low vision | Reflow at high zoom, no horizontal scroll | | Voice control (Dragon) | Motor impairment | Visible labels matching accessible names | | Switch access | Severe motor impairment | Logical focus order, scannable groups | | Eye tracking | Motor impairment | Large targets, dwell-click tolerance | | Braille display | Deaf-blind | Proper text alternatives, semantic structure | | Closed captions | Deaf, hard of hearing | Accurate, synchronized captions | | Alternative keyboard | Motor impairment | Full keyboard operability |


Testing for Accessibility

| Method | What It Catches | Limitations | |--------|----------------|-------------| | Automated scan (axe, Lighthouse) | ~30% of WCAG violations | Cannot assess content quality, logic | | Manual keyboard testing | Focus order, keyboard traps | Requires tester knowledge | | Screen reader testing | Read order, announcements, missing labels | Learning curve for testers | | Color contrast checker | Contrast ratio violations | Does not assess color-only communication | | User testing with disabled users | Real-world usability barriers | Requires recruitment, time |