dist/plugins/web-accessibility-web-accessibility/skills/web-accessibility-web-accessibility/SKILL.md
WCAG, ARIA, keyboard navigation
npx skillsauth add agents-inc/skills web-accessibility-web-accessibilityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Quick Guide: All interactive elements keyboard accessible. Use headless component libraries for ARIA patterns. WCAG AA minimum (4.5:1 text contrast). Proper form labels and error handling. Combine automated axe-core checks with manual keyboard and screen reader testing.
Detailed Resources:
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST ensure all interactive elements are keyboard accessible with visible focus indicators)
(You MUST use headless component libraries for complex ARIA patterns instead of manual implementation)
(You MUST maintain WCAG AA minimum contrast ratios - 4.5:1 for text, 3:1 for UI components)
(You MUST never use color alone to convey information - always add icons, text, or patterns)
</critical_requirements>
Auto-detection: Accessibility (a11y), WCAG compliance, ARIA patterns, keyboard navigation, screen reader support, focus management, aria-label, aria-live, role attribute, skip link
When to use:
prefers-reduced-motionWhen NOT to use:
Target: WCAG 2.2 Level AA compliance (minimum), AAA where feasible
Accessibility ensures digital products are usable by everyone, including users with disabilities. Accessibility is a requirement, not a feature - it should be built in from the start, not retrofitted.
Key philosophy:
CRITICAL: All interactive elements must be keyboard accessible
tabindex="0" - Adds element to natural tab order (use sparingly)tabindex="-1" - Programmatic focus only (modal content, headings)tabindex > 0 (creates unpredictable tab order)outline: none without replacement)element.focus() for dynamic content (search results, error messages)Escape - Close modals, cancel actions, clear selectionsEnter/Space - Activate buttons and linksArrow keys - Navigate lists, tabs, menus, slidersHome/End - Jump to first/last itemTab/Shift+Tab - Navigate between interactive elementsMANDATORY for pages with navigation - place as first focusable element, visually hidden until focused.
// components/skip-link.tsx
export function SkipLink({ className }: { className?: string }) {
return (
<a href="#main-content" className={className}>
Skip to main content
</a>
);
}
See examples/core.md for full skip link implementation with styling.
Use headless component libraries - they handle ARIA automatically for complex patterns like dialogs, selects, tabs, tooltips, and popovers.
Buttons:
aria-label - For icon-only buttonsaria-pressed - For toggle buttonsaria-expanded - For expandable sectionsaria-disabled - Use with disabled attributeForms:
aria-required - Required fields (use with required)aria-invalid - Invalid fieldsaria-describedby - Link to error messages, helper textaria-errormessage - Explicit error message referenceNavigation:
aria-current="page" - Current page in navigationaria-label - Describe navigation purpose ("Main navigation", "Footer navigation")Modals/Dialogs:
role="dialog" or role="alertdialog"aria-modal="true"aria-labelledby - Points to dialog titlearia-describedby - Points to dialog descriptionTables:
scope="col" and scope="row" for headers<caption> for table descriptionaria-sort for sortable columnsUse for dynamic content updates:
aria-live="polite" - Announce when user is idle (status messages, non-critical updates)aria-live="assertive" - Announce immediately (errors, critical alerts)aria-atomic="true" - Announce entire region contentrole="status" - For status messages (implies aria-live="polite")role="alert" - For error messages (implies aria-live="assertive")Best practices:
Text contrast (AA):
Non-text contrast:
Color Independence:
See examples/color.md for contrast examples and design tokens.
Always use semantic HTML:
<button> for actions (not <div onclick>)<a> for navigation (not <div onclick>)<nav> for navigation sections<main> for primary content (one per page)<header> and <footer> for page sections<ul>/<ol> for lists<table> for tabular data (not divs with grid CSS)<form> with proper <label> associationsNever:
<div> or <span> for interactive elementsLabel Associations:
<label> with htmlFor attributeError Handling:
aria-invalid="true" on invalid fieldsaria-describedby linking to error messagerole="alert" on error messages for screen reader announcementSee examples/forms.md for complete form validation and error handling patterns.
Minimum requirements:
Use :focus-visible for better UX:
/* Shows only for keyboard navigation, not mouse clicks */
button:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
See examples/focus.md for full focus indicator patterns.
WCAG 2.2 Target Size Requirements:
See examples/touch-targets.md for sizing and spacing examples.
.sr-only class for screen reader only textaria-label for icon-only buttonsalt="" for decorative imagesaria-hidden="true" for decorative content (but never on focusable elements)See examples/screen-reader.md for sr-only and hiding patterns.
WCAG 2.3.3 Animation from Interactions (AAA):
Motion can cause nausea, dizziness, or vestibular disorders (affects 70+ million people). Use prefers-reduced-motion to respect user preferences:
/* Only animate when user has no motion preference */
@media (prefers-reduced-motion: no-preference) {
.animated-element {
animation: slide-in 300ms ease-out;
}
}
Key principles:
reduce means minimize, not eliminate all motion - essential animations can remainWCAG 2.2 (W3C Recommendation October 2023, ISO/IEC 40500:2025 as of October 2025) added 9 new success criteria. Key ones for developers:
Level A:
Level AA:
Level AAA:
Removed from WCAG 2.2:
Multi-layered approach required - automated tools catch ~57% of WCAG issues. Always combine with manual testing.
Automated: Use axe-core based tools in your test runner for automated WCAG checks. See examples/testing.md for axe integration patterns.
Manual keyboard checklist:
Manual screen reader checklist:
Manual visual checklist:
Screen readers to test with: NVDA (Windows, free), JAWS (Windows, paid), VoiceOver (macOS/iOS, built-in), TalkBack (Android, built-in)
<red_flags>
High Priority Issues:
div or span for buttons/links - no semantic meaning, no keyboard supportMedium Priority Issues:
Gotchas & Edge Cases:
:focus vs :focus-visible - use :focus-visible to avoid focus rings on mouse clicksalt="" is correct for decorative images - don't skip the alt attribute entirelyaria-hidden="true" also hides from keyboard - don't use on focusable elementsrole="button" on <div> doesn't add keyboard support - still need Enter/Space handlersprefers-reduced-motion: reduce means minimize, not eliminate - essential animations can remainSee reference.md for full anti-patterns with code examples.
</red_flags>
Official guidelines:
Tools:
<critical_reminders>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST ensure all interactive elements are keyboard accessible with visible focus indicators)
(You MUST use headless component libraries for complex ARIA patterns instead of manual implementation)
(You MUST maintain WCAG AA minimum contrast ratios - 4.5:1 for text, 3:1 for UI components)
(You MUST never use color alone to convey information - always add icons, text, or patterns)
Failure to follow these rules will make the site unusable for keyboard users, screen reader users, and color-blind users - violating WCAG 2.2 Level AA compliance.
</critical_reminders>
development
Material Design component library for Vue 3
development
VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite
tools
Docusaurus 3.x documentation framework — site configuration, docs/blog plugins, sidebars, versioning, MDX, swizzling, and deployment
development
TanStack Form patterns - useForm, form.Field, validators, arrays, linked fields, createFormHook, type safety