Accessibility Checklist
SkillQuick reference for WCAG 2.1 AA compliance. Use alongside the `frontend-ui-engineering` skill.
Accessibility Checklist
Accessibility Checklist
Quick reference for WCAG 2.1 AA compliance. Use alongside the frontend-ui-engineering skill.
Table of Contents
- Essential Checks
- Common HTML Patterns
- Testing Tools
- Quick Reference: ARIA Live Regions
- Common Anti-Patterns
Essential Checks
Keyboard Navigation
- All interactive elements focusable via Tab key
- Focus order follows visual/logical order
- Focus is visible (outline/ring on focused elements)
- Custom widgets have keyboard support (Enter to activate, Escape to close)
- No keyboard traps (user can always Tab away from a component)
- Skip-to-content link at top of page - visible (at least) on keyboard focus
- Modals trap focus while open, return focus on close
Screen Readers
- All images have
alttext (oralt=""for decorative images) - All form inputs have associated labels (
<label>oraria-label) - Buttons and links have descriptive text (not "Click here")
- Icon-only buttons have
aria-label - Page has one
<h1>and headings don't skip levels - Dynamic content changes announced (
aria-liveregions) - Tables have
<th>headers with scope
Visual
- Text contrast ≥ 4.5:1 (normal text) or ≥ 3:1 (large text, 18px+)
- UI components contrast ≥ 3:1 against background
- Color is not the only way to convey information
- Text resizable to 200% without breaking layout
- No content that flashes more than 3 times per second
Forms
- Every input has a visible label
- Required fields indicated (not by color alone)
- Error messages specific and associated with the field
- Error state visible by more than color (icon, text, border)
- Form submission errors summarized and focusable
- Known fields use autocomplete (for example
type="email" autocomplete="email")
Content
- Language declared (
<html lang="en">) - Page has a descriptive
<title> - Links distinguish from surrounding text (not by color alone)
- Touch targets ≥ 44x44px on mobile
- Meaningful empty states (not blank screens)
Common HTML Patterns
Buttons vs. Links
<!-- Use <button> for actions -->
<button onClick={handleDelete}>Delete Task</button>
<!-- Use <a> for navigation -->
<a href="/tasks/123">View Task</a>
<!-- NEVER use div/span as buttons -->
<div onClick={handleDelete}>Delete</div> <!-- BAD -->
Form Labels
<!-- Explicit label association -->
<label htmlFor="email">Email address</label>
<input id="email" type="email" required />
<!-- Implicit wrapping -->
<label>
Email address
<input type="email" required />
</label>
<!-- Hidden label (visible label preferred) -->
<input type="search" aria-label="Search tasks" />
ARIA Roles
<!-- Navigation -->
<nav aria-label="Main navigation">...</nav>
<nav aria-label="Footer links">...</nav>
<!-- Status messages -->
<div role="status" aria-live="polite">Task saved</div>
<!-- Alert messages -->
<div role="alert">Error: Title is required</div>
<!-- Modal dialogs -->
<dialog aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm Delete</h2>
...
</dialog>
<!-- Loading states -->
<div aria-busy="true" aria-label="Loading tasks">
<Spinner />
</div>
Accessible Lists
<ul role="list" aria-label="Tasks">
<li>
<input type="checkbox" id="task-1" aria-label="Complete: Buy groceries" />
<label htmlFor="task-1">Buy groceries</label>
</li>
</ul>
Testing Tools
# Automated audit
npx axe-core # Programmatic accessibility testing
npx pa11y # CLI accessibility checker
# In browser
# Chrome DevTools → Lighthouse → Accessibility
# Chrome DevTools → Elements → Accessibility tree
# Screen reader testing
# macOS: VoiceOver (Cmd + F5)
# Windows: NVDA (free) or JAWS
# Linux: Orca
Quick Reference: ARIA Live Regions
| Value | Behavior | Use For |
|---|---|---|
aria-live="polite" | Announced at next pause | Status updates, saved confirmations |
aria-live="assertive" | Announced immediately | Errors, time-sensitive alerts |
role="status" | Same as polite | Status messages |
role="alert" | Same as assertive | Error messages |
Common Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
div as button | Not focusable, no keyboard support | Use <button> |
Missing alt text | Images invisible to screen readers | Add descriptive alt |
| Color-only states | Invisible to color-blind users | Add icons, text, or patterns |
| Autoplaying media | Disorienting, can't be stopped | Add controls, don't autoplay |
| Custom dropdown with no ARIA | Unusable by keyboard/screen reader | Use native <select> or proper ARIA listbox |
| Removing focus outlines | Users can't see where they are | Style outlines, don't remove them |
| Empty links/buttons | "Link" announced with no description | Add text or aria-label |
tabindex > 0 | Breaks natural tab order | Use tabindex="0" or -1 only |
Imported from https://github.com/addyosmani/agent-skills by addyosmani. Licensed under MIT. Source: https://github.com/addyosmani/agent-skills/blob/main/references/accessibility-checklist.md