designer/ensuring-accessibility/SKILL.md
Ensure WCAG 2.2 AA compliance covering color contrast, keyboard navigation, screen reader support, accessible forms, and motion preferences.
npx skillsauth add 7a336e6e/skills ensuring-accessibilityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Make every UI component and page meet WCAG 2.2 AA standards. Accessibility is a design constraint applied from the start, not an audit bolted on after implementation.
Check every text/background combination against WCAG AA thresholds:
Check contrast for ALL states: default, hover, focus, disabled, active. Disabled elements are exempt from contrast requirements but should still be distinguishable.
Every interactive element must be:
tabindex="0".onKeyDown handling.outline: none without a replacement.Tab order must follow visual reading order. Use the DOM order to establish logical flow — don't rely on CSS order or tabindex values greater than 0.
Use semantic HTML as the foundation. The correct element communicates its role without ARIA:
<!-- Good: semantic HTML communicates role -->
<button>Save changes</button>
<nav aria-label="Main navigation">
<ul>
<li><a href="/dashboard">Dashboard</a></li>
</ul>
</nav>
<!-- Bad: div soup requiring ARIA to compensate -->
<div role="button" tabindex="0" onclick="save()">Save changes</div>
<div role="navigation" aria-label="Main navigation">
<div role="list">
<div role="listitem"><span onclick="navigate()">Dashboard</span></div>
</div>
</div>
Use ARIA only when HTML semantics are insufficient:
aria-label: when visible text doesn't adequately describe the element (e.g., an icon-only button: <button aria-label="Close dialog">).aria-describedby: to link supplementary descriptions (error messages, help text).aria-live="polite": for dynamic content updates (toast notifications, loading states). Use assertive only for critical, time-sensitive alerts.aria-expanded, aria-controls: for disclosure widgets (accordions, dropdowns).<form novalidate>
<fieldset>
<legend>Shipping address</legend>
<div>
<label for="street">Street address</label>
<input
id="street"
type="text"
autocomplete="street-address"
aria-required="true"
aria-invalid="true"
aria-describedby="street-error"
/>
<p id="street-error" role="alert">
Street address is required.
</p>
</div>
<div>
<label for="city">City</label>
<input
id="city"
type="text"
autocomplete="address-level2"
aria-required="true"
/>
</div>
</fieldset>
<button type="submit">Continue to payment</button>
</form>
Key form rules:
<label> via for/id pairing. Placeholder text is NOT a label.<fieldset> and <legend>.aria-describedby.aria-invalid="true" on fields that have validation errors.aria-required="true" (or the required attribute) for mandatory fields.autocomplete attributes for common fields (name, email, address, phone).Respect user preferences for reduced motion:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
prefers-reduced-motion.<img> needs a descriptive alt attribute. Describe the content, not the decoration ("Chart showing revenue growth from $2M to $5M" not "chart image").alt="" (empty string, NOT omitting the attribute) or CSS background-image.aria-hidden="true" when the icon is decorative or paired with visible text.<button> does not need role="button". A <nav> does not need role="navigation". Adding redundant ARIA is a code smell that suggests the developer doesn't understand when ARIA is needed.tabindex values greater than 0. This overrides the natural DOM order and creates unpredictable tab sequences. Use tabindex="0" to make elements focusable in DOM order, or tabindex="-1" for programmatic focus only.user-scalable=no or maximum-scale=1. Users with low vision depend on zoom.outline: none or outline: 0 without providing a visible alternative. The default browser focus ring is better than no focus ring. If you style custom focus rings, ensure they have at least 3:1 contrast.aria-label on elements that already have visible text content. The aria-label overrides the visible text for screen readers, creating a disconnect between what sighted and non-sighted users perceive.title attributes as the primary accessible name for interactive elements. Title tooltips are inconsistent across browsers and not accessible via keyboard.<!-- aria-live region for async validation messages -->).designer/designing-ui-system/SKILL.md — color tokens must meet contrast requirements.../../frontend/building-components/SKILL.md — component implementation must follow these accessibility patterns (cross-agent contract).development
Implement features using the Red-Green-Refactor cycle to ensure testability and correctness from the start.
data-ai
Manage the `tasks.md` ledger with strict locking and collision avoidance protocols to allow multiple agents to work in parallel safely.
development
The git-workflow skill defines branching conventions, commit message formats, and pull request standards that all agents must follow for consistent version control.
development
The environment-config skill standardizes how agents manage environment variables, secrets, and application configuration across local development and deployed environments.