Production WCAG AA without accessibility theater — the real engineering cost, tooling stack, and the accessibility mistakes teams repeatedly ship.
WCAG AA is one of those phrases that gets a checkbox in a kickoff doc and then
forgets to ship. Three months later the build goes out the door, the contrast
ratio is 3.2:1 on body text, the modal traps focus but never returns it on
close, and the “Add to cart” button is a clickable div.
The audit lands, the rework lands, and the cost of fixing it after launch is
roughly four times the cost of building it in.
Accessible Is a Checklist, Not a Feeling
WCAG 2.1 AA is a specific list of measurable requirements. Not a vibe. Not “we care about everyone.” A specific list.Core Accessibility Requirements
- Body text contrast ratio 4.5:1 or higher
- Large text contrast ratio 3:1 or higher
- Non-text UI contrast ratio 3:1 or higher
- Touch target size minimum 44×44 CSS pixels
- Keyboard-only navigation support
- Programmatically labeled form controls
- Descriptive alt text for images
The Five Checks Every PR Runs
1. axe-core Scan in CI
Automated accessibility scans catch missing labels, broken ARIA attributes, contrast failures, and invalid markup before merge.npx axe-core http://localhost:6006 --tags wcag2a,wcag2aa --exit
2. Lighthouse Accessibility Audit
npx lighthouse http://localhost:3000 --only-categories=accessibility
Teams should hold a minimum Lighthouse accessibility score of 95.
3. eslint-plugin-jsx-a11y
- click-events-have-key-events
- no-static-element-interactions
- label-has-associated-control
- anchor-is-valid
4. Design Token Contrast Checks
const ratio = getContrast(fg, bg);
if (ratio < min) {
process.exit(1);
}
This prevents inaccessible color combinations from entering production.
5. Pa11y Journey Testing
Pa11y validates accessibility across real user journeys like signup, checkout, and settings.What Automated Tools Catch — And What They Miss
Automated Tools Catch
- Missing labels
- Contrast failures
- Broken ARIA usage
- Heading structure problems
- Duplicate IDs
Automated Tools Miss
- Poor screen-reader UX
- Incorrect tab order
- Weak focus indicators
- Meaningless alt text
- Confusing reading order
The Screen Reader Pass
Every production page should receive a manual screen-reader walkthrough before launch using NVDA or VoiceOver.Accessibility tooling is a tripwire — not certification.
Three Accessibility Patterns That Fail Real Users
1. Color-Only Error States
<input aria-invalid="true"
aria-describedby="email-error" />
<span id="email-error">
Email is required
</span>
2. Custom Dropdowns Built on div Elements
Custom selects are among the most common accessibility failures in frontend systems. Prefer native select elements or accessible component libraries.3. Modals That Do Not Restore Focus
useEffect(() => {
if (open) {
triggerRef.current = document.activeElement;
} else if (triggerRef.current) {
triggerRef.current.focus();
}
}, [open]);