Agent skill
accessibility-auditing
Audit web pages and components for accessibility issues following WCAG 2.1 guidelines. Use when checking for accessibility compliance, fixing a11y issues, ensuring screen reader compatibility, or improving keyboard navigation. Triggers on requests like "audit accessibility", "check a11y", "fix accessibility issues", "screen reader support", "keyboard navigation", or "WCAG compliance".
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/accessibility-auditing-paulirv-peabod-web
SKILL.md
Accessibility Auditing
Audit and improve accessibility for WCAG 2.1 AA compliance.
Process
- Identify scope - Which pages/components to audit?
- Automated checks - Run linting and browser tools
- Manual testing - Keyboard navigation, screen reader
- Document issues - Severity, location, fix
- Implement fixes - Priority order
WCAG 2.1 Checklist
Perceivable
Images
// Required: alt text for informational images
<img src={article.image} alt={article.imageAlt || article.title} />
// Decorative images: empty alt
<img src="/decorative-border.png" alt="" role="presentation" />
Color Contrast
- Normal text: 4.5:1 minimum
- Large text (18px+): 3:1 minimum
- Use theme CSS variables which meet contrast requirements
Video/Audio
// Captions for video content
<video>
<track kind="captions" src="/captions.vtt" srclang="en" label="English" />
</video>
Operable
Keyboard Navigation
// All interactive elements focusable
<button onClick={handleClick}>Click me</button> // Good: button is focusable
// Custom elements need tabindex
<div role="button" tabIndex={0} onClick={handleClick} onKeyDown={handleKeyDown}>
Click me
</div>
// Skip links for main content
<a href="#main-content" className="sr-only focus:not-sr-only">
Skip to main content
</a>
Focus Indicators
// Visible focus states
className="focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
Focus Trapping (Modals)
// Trap focus within modal
useEffect(() => {
const focusableElements = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const first = focusableElements[0];
const last = focusableElements[focusableElements.length - 1];
function handleTab(e: KeyboardEvent) {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
}
// ...
}, []);
Understandable
Form Labels
// Always associate labels with inputs
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" />
// Or use aria-label for icon-only buttons
<button aria-label="Close modal">
<XIcon />
</button>
Error Messages
// Associate errors with inputs
<input
id="email"
aria-invalid={!!error}
aria-describedby={error ? "email-error" : undefined}
/>
{error && (
<p id="email-error" role="alert" className="text-red-500">
{error}
</p>
)}
Language
// Declare page language
<html lang="en">
Robust
Semantic HTML
// Use appropriate elements
<nav>...</nav> // Navigation
<main>...</main> // Main content
<article>...</article> // Article content
<aside>...</aside> // Sidebar
<header>...</header> // Header
<footer>...</footer> // Footer
// Use headings in order
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
ARIA Roles and States
// Live regions for dynamic content
<div aria-live="polite" aria-atomic="true">
{statusMessage}
</div>
// Loading states
<button aria-busy={loading} disabled={loading}>
{loading ? 'Saving...' : 'Save'}
</button>
// Expanded/collapsed
<button aria-expanded={isOpen} aria-controls="menu">
Menu
</button>
<div id="menu" hidden={!isOpen}>...</div>
Common Issues in This Project
Admin Tables
- Ensure sortable columns are keyboard accessible
- Add scope attributes to table headers
- Announce sort changes with aria-live
Media Library
- All images need alt text (use title field)
- Video players need keyboard controls
- Upload progress announced to screen readers
Forms
- All fields need visible labels
- Required fields marked with aria-required
- Error states linked with aria-describedby
Navigation
- Mobile menu needs aria-expanded
- Current page indicated with aria-current="page"
- Dropdown menus keyboard navigable
Testing Tools
# ESLint a11y plugin (add to eslint.config.mjs)
npm install eslint-plugin-jsx-a11y --save-dev
# Playwright a11y testing
npm install @axe-core/playwright --save-dev
Output
Provide accessibility audit results:
- Issue list with severity (Critical/Serious/Moderate/Minor)
- WCAG criterion violated
- Location (file:line or selector)
- Recommended fix with code example
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?