
WCAG Compliance Checklist: Complete Guide for Developers (2025)
WCAG Compliance Checklist: Complete Guide for Developers (2025)
WCAG (Web Content Accessibility Guidelines) has 78 success criteria across 4 principles. That's overwhelming.
This checklist distills WCAG 2.1 Level AA into actionable items you can complete in order of priority. Follow this, and you'll achieve solid accessibility compliance.
How to Use This Checklist
Priority levels:
- π΄ Critical - Legal requirement, breaks core functionality (fix immediately)
- π‘ Important - Required for compliance (fix within 1 month)
- π’ Enhancement - Improves UX but not legally required (fix when convenient)
Estimated time: 2-4 weeks for a typical website (depends on size and complexity)
Principle 1: Perceivable
Content must be perceivable to all users.
Images & Media
π΄ 1.1.1 - Non-text Content (Level A)
- All images have
alttext - Decorative images use
alt=""androle="presentation" - Complex images (charts, diagrams) have detailed descriptions
- Icon buttons have accessible names
// β Good examples <img src="product.jpg" alt="Blue cotton t-shirt with crew neck" /> <img src="divider.svg" alt="" role="presentation" /> <button aria-label="Close dialog"> <XIcon aria-hidden="true" /> </button>
π΄ 1.2.1 - Audio-only and Video-only (Level A)
- Audio-only content has text transcript
- Video-only content has audio description or transcript
π‘ 1.2.2 - Captions (Level A)
- Pre-recorded videos have captions
- Live videos have live captions (if feasible)
π‘ 1.2.3 - Audio Description or Media Alternative (Level A)
- Videos have audio descriptions or text alternative
Color & Contrast
π΄ 1.4.3 - Contrast (Minimum) (Level AA)
- Normal text: 4.5:1 contrast ratio
- Large text (24px+ or 19px+ bold): 3:1 contrast ratio
- UI components: 3:1 contrast ratio
/* β Passes WCAG AA */ .text-primary { color: #1A1A1A; /* 16.9:1 on white */ } .text-secondary { color: #595959; /* 7.0:1 on white */ } .button-primary { background: #0056B3; /* 4.8:1 on white */ color: #FFFFFF; }
Tool: Use WebAIM Contrast Checker (opens in new tab)
π‘ 1.4.1 - Use of Color (Level A)
- Information isn't conveyed by color alone
- Links are distinguishable without color (use underline)
// β Bad: Color only <span className="text-red-500">Error</span> // β Good: Icon + color <span className="text-red-500"> <ErrorIcon aria-hidden="true" /> Error </span>
π‘ 1.4.4 - Resize Text (Level AA)
- Text can be resized to 200% without loss of content or functionality
- Test by zooming browser to 200%
π‘ 1.4.10 - Reflow (Level AA)
- Content reflows at 320px width (no horizontal scrolling)
- Responsive design works on mobile
π‘ 1.4.11 - Non-text Contrast (Level AA)
- UI components have 3:1 contrast ratio
- Focus indicators have 3:1 contrast
Principle 2: Operable
Users must be able to operate interface components.
Keyboard Accessibility
π΄ 2.1.1 - Keyboard (Level A)
- All functionality available via keyboard
- Tab key moves through all interactive elements
- Enter/Space activates buttons and links
- Escape closes dialogs and modals
// β Bad: onClick on div <div onClick={handleDelete}>Delete</div> // β Good: Semantic button <button onClick={handleDelete}>Delete</button>
π΄ 2.1.2 - No Keyboard Trap (Level A)
- Focus can move away from all components
- Modals can be closed with Escape key
- No infinite focus loops
π‘ 2.1.4 - Character Key Shortcuts (Level A)
- Single-character shortcuts can be turned off or remapped
Navigation
π΄ 2.4.1 - Bypass Blocks (Level A)
- "Skip to main content" link exists
- Skip link is visible on focus
<a href="#main" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2 focus:bg-blue-600 focus:text-white" > Skip to main content </a> <main id="main"> {/* Page content */} </main>
π‘ 2.4.2 - Page Titled (Level A)
- Every page has unique
<title> - Title describes page content
// Next.js example export const metadata = { title: 'Pricing Plans | AccessMend', description: 'Affordable WCAG compliance for every business', };
π‘ 2.4.3 - Focus Order (Level A)
- Tab order is logical (matches visual order)
- No random focus jumps
π΄ 2.4.7 - Focus Visible (Level AA)
- All focusable elements have visible focus indicator
- Focus indicator has 3:1 contrast ratio
/* β Accessible focus styles */ *:focus-visible { outline: 3px solid #0066CC; outline-offset: 2px; } button:focus-visible { outline: 3px solid #0066CC; outline-offset: 2px; }
π‘ 2.4.6 - Headings and Labels (Level AA)
- Headings describe content accurately
- Form labels are descriptive
Timing
π‘ 2.2.1 - Timing Adjustable (Level A)
- Time limits can be turned off, adjusted, or extended
- Sessions don't expire without warning
π‘ 2.2.2 - Pause, Stop, Hide (Level A)
- Auto-playing content can be paused
- Carousels have play/pause button
Seizures
π‘ 2.3.1 - Three Flashes or Below Threshold (Level A)
- No content flashes more than 3 times per second
##Principle 3: Understandable
Information and operation must be understandable.
Forms
π΄ 3.3.1 - Error Identification (Level A)
- Form errors are clearly identified
- Error messages explain what went wrong
<div className="form-group"> <label htmlFor="email">Email *</label> <input id="email" aria-invalid={!!errors.email} aria-describedby="email-error" /> {errors.email && ( <span id="email-error" role="alert" className="error"> {errors.email} </span> )} </div>
π΄ 3.3.2 - Labels or Instructions (Level A)
- All form inputs have labels
- Required fields are marked
<label htmlFor="password"> Password * <span className="sr-only">(required)</span> </label> <input id="password" type="password" required aria-required="true" />
π‘ 3.3.3 - Error Suggestion (Level AA)
- Error messages provide suggestions for fixing
// β Not helpful "Invalid input" // β Helpful "Email must include @ symbol. Example: user@example.com"
π‘ 3.3.4 - Error Prevention (Level AA)
- Submissions can be reversed, checked, or confirmed
- Use confirmation dialogs for destructive actions
Language
π΄ 3.1.1 - Language of Page (Level A)
- HTML has
langattribute
<html lang="en">
π‘ 3.1.2 - Language of Parts (Level AA)
- Content in different languages is marked
<p>The French word for hello is <span lang="fr">bonjour</span>.</p>
Predictability
π‘ 3.2.1 - On Focus (Level A)
- Receiving focus doesn't trigger unexpected changes
π‘ 3.2.2 - On Input (Level A)
- Changing settings doesn't cause unexpected context changes
π‘ 3.2.3 - Consistent Navigation (Level AA)
- Navigation order is consistent across pages
π‘ 3.2.4 - Consistent Identification (Level AA)
- Icons and components have consistent meaning across site
Principle 4: Robust
Content must be robust enough to work with assistive technologies.
HTML & ARIA
π΄ 4.1.1 - Parsing (Level A)
- HTML is valid (no duplicate IDs, proper nesting)
- Run through W3C validator
π΄ 4.1.2 - Name, Role, Value (Level A)
- All UI components have accessible names
- Roles are defined correctly
- States are communicated
// Custom checkbox <div role="checkbox" aria-checked={isChecked} aria-labelledby="checkbox-label" tabIndex={0} onKeyDown={(e) => { if (e.key === ' ') { e.preventDefault(); setIsChecked(!isChecked); } }} > {isChecked && <CheckIcon />} </div> <span id="checkbox-label">Accept terms</span>
π‘ 4.1.3 - Status Messages (Level AA)
- Status messages use
role="status"orrole="alert"
<div role="status" aria-live="polite"> Item added to cart </div> <div role="alert" aria-live="assertive"> Error: Please fill out all required fields </div>
Quick Audit Tools
-
Automated scans:
- AccessMend - Free, no signup
- axe DevTools browser extension
- Lighthouse in Chrome DevTools
-
Manual tests:
- Tab through entire site (keyboard only)
- Test with NVDA or VoiceOver screen reader
- Zoom to 200% and verify layout
-
Color contrast:
Priority Action Plan
Week 1: Critical Fixes
- Add alt text to all images
- Fix color contrast violations
- Ensure keyboard accessibility
- Add form labels
- Create skip navigation link
Week 2: Important Fixes
- Add page titles
- Fix heading hierarchy
- Add focus indicators
- Implement error handling
Week 3: Testing & Refinement
- Screen reader testing
- Keyboard navigation testing
- Mobile accessibility testing
Week 4: Documentation
- Create accessibility statement
- Document known issues
- Train team on accessibility
Common Failures & Quick Fixes
| Issue | Quick Fix | Time |
|---|---|---|
| Missing alt text | Add descriptive alt attributes | 1 hour |
| Low color contrast | Darken text colors (use gray-700+) | 2 hours |
| No keyboard access | Replace divs with buttons/links | 4 hours |
| Missing form labels | Add <label> elements | 2 hours |
| No focus indicators | Add focus:ring-2 styles | 1 hour |
Resources
- WCAG 2.1 Quick Reference (opens in new tab)
- AccessMend Free Scanner
- A11y Project Checklist (opens in new tab)
- WebAIM Articles (opens in new tab)
Final Checklist
Before launch:
- Run automated accessibility scan
- Test with keyboard only
- Test with screen reader (NVDA/VoiceOver)
- Test on mobile device
- Zoom to 200% and verify layout
- Create accessibility statement page
- Document any known issues with fix timeline
WCAG compliance isn't a one-time projectβit's an ongoing process. Use this checklist for every new feature.
Need help getting started? Run a free accessibility audit or view a sample report to see what violations look like.
Ready to fix accessibility issues?
Get a free WCAG compliance report for your website in seconds.
Related Articles
WCAG 2.2: What's New in 2025 and How It Affects Your Website
WCAG 2.2 introduces 9 new success criteria that could impact your website's accessibility compliance. Learn what changed and how to adapt your accessibility strategy for 2025.
Read moreReact Accessibility: Complete Guide with Code Examples (2025)
Building accessible React apps requires more than semantic HTML. Learn ARIA patterns, keyboard navigation, focus management, and testing strategies with production-ready code examples.
Read moreColor Contrast for Accessibility: Complete Guide with Examples
Color contrast violations are the #1 most common WCAG failure. Learn the exact ratios required, how to test them, and see before/after examples that pass compliance.
Read more