Skip to content
Back to skills

A11y Scan

ASecurity

Run axe-core / Pa11y / Lighthouse against changed pages and classify findings by WCAG level (A / AA / AAA). Use when shipping or reviewing UI changes, before a release accessibility gate, or when asked for an a11y audit.

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
ai-agentsgobashnodetestinggitfrontendbackend

Works with

  • cli

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add bakw00ds/yakos --skill a11y-scan --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of A11y Scan?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for A11y Scan
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/bakw00ds-a11y-scan/badge)](https://www.skillsdirectory.com/skills/bakw00ds-a11y-scan)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: a11y-scan
description: Run axe-core / Pa11y / Lighthouse against changed pages and classify findings by WCAG level (A / AA / AAA). Use when shipping or reviewing UI changes, before a release accessibility gate, or when asked for an a11y audit.
allowed-tools: Bash Read
argument-hint: "[--pages <glob>] [--level A|AA|AAA] [--baseline <file>]"
mode: [audit]
---

# A11y Scan

## Purpose

Run accessibility tooling (axe-core, Pa11y, Lighthouse) against the
pages a change touches, classify findings by WCAG conformance level,
and emit a markdown report with severity-tagged remediations. Designed
for the `accessibility-reviewer` agent and any frontend PR that
touches user-facing surface.

## Scope

- Targets pages affected by the diff (or an explicit `--pages` glob).
- Runs axe-core for rule-based scanning, Pa11y for HTML_CodeSniffer
  rules, and Lighthouse for the broader a11y category score.
- Cross-references findings against WCAG 2.2 success criteria and
  classifies each as Level A (must), AA (should — most regulated
  baselines), or AAA (nice-to-have, rarely required).
- Emits a markdown report; does NOT auto-fix. Remediation is
  dispatched to `frontend` / `accessibility-reviewer`.

## When to use

- Before merging any PR that touches a user-facing page, component,
  or design-system primitive.
- After a design-system version bump, against representative pages,
  to catch regressions.
- For regulated projects (EU EAA-2025, ADA Title II, Section 508),
  on every release as a compliance gate.

## When NOT to use

- For backend-only changes — no DOM, no findings.
- For purely internal admin tools where the operator has explicitly
  scoped a11y out of policy (rare; surface this for explicit human
  approval first).
- As a substitute for manual screen-reader testing — automated tools
  catch ~30-40% of WCAG issues. Manual testing covers the rest.

## Automated pass

1. Resolve target pages from the diff or `--pages`:
   ```sh
   if [ -n "${PAGES:-}" ]; then
       targets="$PAGES"
   else
       # Heuristic: any changed file under app/ pages/ src/routes/
       # maps to a route. Project may override via
       # .claude/a11y-page-map.sh
       targets=$(git diff --name-only origin/main...HEAD \
           | grep -E '^(app|pages|src/routes|src/pages)/' \
           | sort -u)
   fi
   ```

2. Spin up the project's dev server (or use `--baseline` URL):
   ```sh
   # Project supplies a11y-serve.sh that brings up the app on
   # http://localhost:${PORT:-3000} and exits when ready.
   .claude/a11y-serve.sh &
   serve_pid=$!
   trap 'kill $serve_pid 2>/dev/null' EXIT
   ```

3. Run the three scanners per page:
   ```sh
   for page in $targets; do
       url="http://localhost:${PORT:-3000}/${page}"
       npx @axe-core/cli "$url" --save "/tmp/axe-$page.json"
       npx pa11y --reporter json --standard WCAG2AA "$url" \
           > "/tmp/pa11y-$page.json"
       npx lighthouse "$url" --only-categories=accessibility \
           --output=json --output-path="/tmp/lh-$page.json" \
           --chrome-flags="--headless"
   done
   ```

4. Parse + classify. Each axe / Pa11y violation maps to one or more
   WCAG criteria; the rule metadata includes the level. Group by:
   - **Level A failures** — block merge.
   - **Level AA failures** — block merge for regulated projects;
     warn for others.
   - **Level AAA failures** — informational.
   - **Lighthouse score delta** — flag any drop ≥5 points from
     baseline.

5. Compose the markdown report:
   - One section per page.
   - Per-finding: WCAG criterion, level, scanner, selector, suggested
     fix, link to WCAG quick-ref.
   - Top-of-report summary: total findings by level, pass/fail
     verdict, comparison to baseline if provided.

6. Exit code: 0 if no Level-A/AA failures (or all are baselined-as-
   accepted), 1 otherwise. CI gate hooks on this.

## Manual pass

For a quick spot-check on a single URL:

```sh
npx @axe-core/cli http://localhost:3000/checkout
npx pa11y --standard WCAG2AA http://localhost:3000/checkout
npx lighthouse http://localhost:3000/checkout --only-categories=accessibility --view
```

…and read the human-formatted output directly. Skip the report
composition for one-off checks.

## Known gotchas

- **Dynamic content.** Scanners snapshot the DOM at one moment.
  Pages with carousels, modals, lazy-loaded content need the
  scanner driven through the interaction (axe `frameWaitTime`,
  Pa11y `actions`). Configure per-page in
  `.claude/a11y-page-config.json`.
- **False positives on color contrast.** Gradient backgrounds and
  semi-transparent overlays trip the contrast rule. Verify in a
  browser dev-tool eyedropper before filing the finding.
- **Component-library findings.** A finding in
  `node_modules/<design-system>/...` is the design system's bug, not
  the project's. File upstream; baseline-accept locally with a
  reference to the upstream issue.
- **Lighthouse scoring is non-deterministic.** Run 3x and take the
  median if the score is borderline. CI flake on Lighthouse score
  alone is a known industry pattern.
- **`role=presentation` does not erase children.** Findings on
  hidden-but-not-aria-hidden content are real; visually-hidden CSS
  is not the same as `aria-hidden=true`.
- **Locale.** Run against the default locale; `lang=` attribute
  failures only fire on the default. Multi-locale projects need a
  pass per locale in regulated contexts.

## References

- `lib/agents/accessibility-reviewer.md` — primary consumer.
- WCAG 2.2 quick-reference: https://www.w3.org/WAI/WCAG22/quickref/
- axe-core rules: https://dequeuniversity.com/rules/axe/
- Pa11y standards: WCAG2A / WCAG2AA / WCAG2AAA / Section508.
- `.claude/a11y-page-map.sh` (project-supplied) — file→URL mapping.
- `.claude/a11y-page-config.json` (project-supplied) — per-page
  scanner overrides.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…