Introduction
The Web Content Accessibility Guidelines (WCAG) are the international standard for web accessibility. But reading the spec is daunting — dozens of criteria, abstract language, and no code examples. This guide translates WCAG 2.2 into practical, actionable advice for developers.
WCAG has three conformance levels: A (minimum), AA (standard target), and AAA (enhanced). Most organizations target AA, which covers the vast majority of accessibility needs. Each criterion maps to a specific user need — understanding the 'why' makes the 'how' intuitive.
This guide focuses on the criteria most relevant to web applications, with code examples and testing strategies for each.
Key Concepts
The Four Principles (POUR)
- Perceivable — Information must be presentable in ways all users can perceive (alt text, captions, contrast)
- Operable — UI must be operable by all users (keyboard, timing, seizures, navigation)
- Understandable — Content must be understandable (readable, predictable, error help)
- Robust — Content must be robust enough for diverse user agents (valid HTML, ARIA, compatibility)
Key Level AA Criteria
// 1.1.1 Non-text Content — All images need alt text
<img src="chart.png" alt="Revenue increased 23% in Q4 2025" />
<img src="decorative-wave.svg" alt="" /> {/* Decorative: empty alt */}
// 1.4.3 Contrast Minimum — 4.5:1 for normal text, 3:1 for large text
// Use: https://webaim.org/resources/contrastchecker/
.text-body { color: #374151; } /* on white: 10.3:1 ✅ */
.text-muted { color: #9CA3AF; } /* on white: 2.9:1 ❌ */
// 2.1.1 Keyboard — All functionality via keyboard
<button onClick={handleAction}>Action</button> // ✅ Focusable, Enter/Space
<div onClick={handleAction}>Action</div> // ❌ Not keyboard accessible
// 2.4.7 Focus Visible — Focus indicator must be visible
button:focus-visible {
outline: 2px solid #3B82F6;
outline-offset: 2px;
}
Practical Examples
1. Accessible Page Structure
<body>
<a href="#main" className="sr-only focus:not-sr-only">Skip to content</a>
<header>
<nav aria-label="Main navigation">
<ul>{/* nav items */}</ul>
</nav>
</header>
<main id="main">
<h1>Page Title</h1>
<section aria-labelledby="section-title">
<h2 id="section-title">Section</h2>
<p>Content...</p>
</section>
</main>
<footer>{/* footer */}</footer>
</body>
2. Accessible Form
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email address</label>
<input id="email" type="email" aria-describedby="email-help email-error"
aria-invalid={!!errors.email} required />
<p id="email-help" className="text-sm text-gray-500">We'll never share your email.</p>
{errors.email && <p id="email-error" role="alert" className="text-red-500">{errors.email}</p>}
</div>
<button type="submit">Subscribe</button>
</form>
3. Live Region for Dynamic Content
// Announce changes to screen readers
<div aria-live="polite" aria-atomic="true">
{notification && <p>{notification}</p>}
</div>
// For urgent messages
<div role="alert">
{error && <p>Error: {error.message}</p>}
</div>
Best Practices
- ✅ Use semantic HTML first — <button>, <nav>, <main>, <form> provide free accessibility
- ✅ Test with keyboard only — Tab, Enter, Space, Escape, Arrow keys
- ✅ Maintain a logical heading hierarchy — h1 → h2 → h3, no skipping
- ✅ Provide skip links for keyboard users to bypass navigation
- ✅ Use aria-live regions for dynamic content updates
- ❌ Don't use div/span with click handlers — use button or anchor
- ❌ Don't rely on color alone to convey information — add text or icons too
Common Pitfalls
- Hiding focus outlines with outline: none without providing an alternative
- Using aria-label on elements that already have visible text — confuses screen readers
- Auto-playing media without pause controls — violates WCAG 1.4.2
- Dynamic content changes not announced — use aria-live regions for updates
Related Guides
- Screen Reader Testing — Verify your WCAG compliance with real assistive technology
- ARIA Attributes Guide — When and how to use ARIA
- Keyboard Accessibility Guide — Deep dive into keyboard navigation
- Color Accessibility Beyond Contrast — Go beyond the minimum contrast ratios