# A11Y

> Accessibility audit for frontend changes — WCAG 2.2 AA, screen-reader compatibility, keyboard navigation, focus management, ARIA correctness, color contrast, and reduced-motion. Static diff-scoped analysis (safe to auto-run) plus an optional dynamic axe pass against a running app. Use when asked to "check accessibility", "a11y audit", "screen reader check", "WCAG", "is this accessible", "keyboard navigation", "ARIA review", or after heavy frontend work.

- Skill: `ariadoss/a11y` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ariadoss/a11y`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ariadoss/a11y/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: ariadoss (https://skillmd.com/u/ariadoss)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ariadoss/a11y

---


# /a11y

Audit frontend changes for accessibility. Two layers:

- **Static (safe to auto-run, diff-only):** read the changed JSX/TSX/Vue/Svelte/
  HTML/CSS and flag accessibility defects from the markup itself — no browser, no
  external tools.
- **Dynamic (recommend / opt-in):** when a dev URL is reachable, run an
  axe-core / Chrome DevTools MCP pass for computed contrast, focus order, and the
  screen-reader accessibility tree — things you can't see from source alone.

## Hard rules

- **Ground every finding in evidence:** file:line, the offending element, the WCAG
  success criterion (e.g. 1.1.1, 2.4.3, 4.1.2), and the concrete user impact
  ("screen-reader users hear an unlabeled button", "keyboard users can't reach X").
- **Severity by user impact, not by rule pedantry.** A control no screen-reader or
  keyboard user can operate is CRITICAL; a missing `lang` attribute is LOW.
- **Smallest correct fix.** Prefer native semantics (`<button>`, `<label>`, `<nav>`)
  over ARIA bolted onto a `<div>`. The first rule of ARIA: don't use ARIA if a
  native element does the job.
- **Scope to the diff.** Audit changed components, not the whole app.

## When this is worth running (the trigger)

Run on **heavy frontend changes likely to affect assistive tech**, not every style
tweak. Trigger when the diff includes any of:

- new/changed **interactive components** (buttons, links, menus, tabs, dialogs,
  tooltips, accordions, comboboxes, drag-drop)
- **forms** (inputs, labels, validation, error messaging)
- **images / media / icons** (alt text, decorative vs informative, captions)
- **ARIA** attributes, `role=`, `tabindex`, or `aria-*` props
- **focus / keyboard** handling (`onKeyDown`, `focus()`, focus traps, route changes,
  modal open/close)
- **color / contrast** changes in styles, or conveying state by color alone
- **motion / animation** (autoplay, transitions, parallax)

A pure copy/spacing CSS change with none of the above does **not** need `/a11y`.

## What to check (WCAG 2.2 AA, screen-reader first)

1. **Semantics & landmarks** — real `<button>`/`<a>`/`<nav>`/`<main>`; one `<h1>`,
   no skipped heading levels; lists are lists. (1.3.1, 2.4.1)
2. **Name, role, value** — every control has an accessible name (visible `<label>`,
   `aria-label`, or text); custom widgets expose correct role + state. Flag
   `<div onClick>` with no role/tabindex/keyboard handler. (4.1.2)
3. **Images & icons** — informative images have meaningful `alt`; decorative ones
   have `alt=""`/`aria-hidden`; icon-only buttons have an accessible name. (1.1.1)
4. **Forms** — every input has an associated `<label for>`/`aria-labelledby`; errors
   are programmatically tied (`aria-describedby`) and announced; `autocomplete`
   where relevant. (1.3.1, 3.3.1, 3.3.2)
5. **Keyboard** — all interactive elements reachable and operable by keyboard;
   visible focus indicator; logical focus order; no keyboard traps; skip link for
   repeated nav. (2.1.1, 2.4.3, 2.4.7, 2.1.2)
6. **Focus management** — on modal/dialog open, focus moves in and is trapped; on
   close, focus returns to the trigger; on SPA route change, focus/announce the new
   view. (2.4.3)
7. **Screen-reader announcements** — dynamic updates use `aria-live`/`role=status`;
   visually-hidden text (`sr-only`) where context is visual-only;
   `aria-hidden` never on focusable content. (4.1.3)
8. **Color & contrast** — text ≥ 4.5:1 (≥ 3:1 large), UI/graphics ≥ 3:1; never
   convey meaning by color alone (pair with icon/text). (1.4.3, 1.4.11, 1.4.1)
9. **Motion & reduced motion** — honor `prefers-reduced-motion`; no autoplay > 5s
   without controls; nothing flashes > 3×/sec. (2.3.1, 2.2.2)
10. **Reflow & zoom** — usable at 200% zoom / 320px without loss of content; no
    `user-scalable=no`; touch targets ≥ 24×24px. (1.4.10, 1.4.4, 2.5.8)

## Steps

1. **Scope** — resolve the changed frontend files (or `$ARGUMENTS` globs). If none
   match the trigger, say so and stop.
2. **Static pass** — Grep/Read the changed files for the defect signatures in each
   dimension above. Record findings with file:line + WCAG criterion + impact.
3. **Dynamic pass (if a dev URL is given or in `CLAUDE.md`/`package.json`)** — load
   the affected routes and run axe-core via the `chrome-devtools` MCP (or a project
   axe runner). Report computed contrast failures, focus-order issues, and
   accessibility-tree gaps the static pass can't see. If no URL is reachable, record
   **dynamic pass SKIPPED (no dev server)** — don't silently drop it.
4. **Report** — group by severity; give the smallest fix per finding (prefer native
   semantics). Draft the corrected markup as a code block; do not apply it.

## Report format

```markdown
# Accessibility audit — <scope> @ <date>

## CRITICAL (blocks assistive-tech users)
- <file:line> — <element> — WCAG <criterion> — <impact> — <fix>

## SERIOUS / MODERATE / MINOR
- …

## Dynamic pass
- axe: N violations (or: SKIPPED — no dev server)
```

## Anti-patterns (do not do)

- Adding ARIA to "fix" something a native element already does correctly.
- Flagging style-only diffs with no interactive/semantic/contrast change.
- Reporting "low contrast" without the measured ratio (use the dynamic pass).
- Applying fixes — this audits and drafts; the user (or `/design-review`) applies.

## Related commands

- `/design-audit` — broader visual/UX audit; `/a11y` is the deeper accessibility
  layer. Run them together on UI changes.
- `/web-perf` — the performance counterpart for frontend changes.
- `/design-review` — *fixes and commits* visual + a11y issues this audit finds.
- `/qa-only` — functional browser QA; pairs with `/a11y` (works + accessible).

