Accessibility Checklist

Skill

Quick reference for WCAG 2.1 AA compliance. Use alongside the `frontend-ui-engineering` skill.

addyosmani·Community·v1.0.0

Accessibility Checklist

Accessibility Checklist

Quick reference for WCAG 2.1 AA compliance. Use alongside the frontend-ui-engineering skill.

Table of Contents

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 alt text (or alt="" for decorative images)
  • All form inputs have associated labels (<label> or aria-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-live regions)
  • 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

ValueBehaviorUse For
aria-live="polite"Announced at next pauseStatus updates, saved confirmations
aria-live="assertive"Announced immediatelyErrors, time-sensitive alerts
role="status"Same as politeStatus messages
role="alert"Same as assertiveError messages

Common Anti-Patterns

Anti-PatternProblemFix
div as buttonNot focusable, no keyboard supportUse <button>
Missing alt textImages invisible to screen readersAdd descriptive alt
Color-only statesInvisible to color-blind usersAdd icons, text, or patterns
Autoplaying mediaDisorienting, can't be stoppedAdd controls, don't autoplay
Custom dropdown with no ARIAUnusable by keyboard/screen readerUse native <select> or proper ARIA listbox
Removing focus outlinesUsers can't see where they areStyle outlines, don't remove them
Empty links/buttons"Link" announced with no descriptionAdd text or aria-label
tabindex > 0Breaks natural tab orderUse 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