agentleFS
lc-dlc-d/deep-a11y-web-skill/skills/a11y-page-audit/SKILL.md

a11y-page-audit

Skill2 starsChanged 30 days agoMITView on GitHub

Audit a single page for accessibility issues using Lighthouse, axe-core, and live browser inspection, then with user permission fix them per WCAG 2.2 and the WAI-ARIA APG patterns. Use when asked to audit, check, or fix a web page's accessibility (a11y, WCAG, screen reader or keyboard support, contrast, alt text, ARIA widget patterns), or to run Lighthouse/axe accessibility checks.

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. glrodasz/dotfiles★ 20same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. About 0 are common, 11 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If you have Chrome DevTools MCP or the claude-in-chrome browser tool available, use it too — it gives you live DOM/accessibility-tree …

    line 35
  2. Distinctive:

    Run Lighthouse (accessibility category) and axe-core against the given URL only — don't follow links to other pages.

    line 43
  3. Distinctive:

    If a browser tool is available, inspect the live accessibility tree and exercise the page by keyboard — automated tools miss most of what …

    line 45
  4. Distinctive:

    Check the WCAG 2.2 criteria that apply to what's on the page, using the per-criterion files indexed in references/WCAG-CRITERIA.md — this …

    line 48
  5. Very specific:

    Read the .axe.json / .lighthouse.json files for node-level detail (selectors, HTML snippets, failure summaries) once you know which rules …

    line 81
  6. Very specific:

    Use run-axe.mjs rather than @axe-core/cli: the CLI's chromedriver dependency fails to install (ERR_REQUIRE_ESM), while run-axe.mjs drives …

    line 84
  7. Distinctive:

    If no browser tool is available, do this manually in a real browser and note it in the report as a pending manual check rather than …

    line 111
  8. Distinctive:

    Every interactive web component must match, or at least reference, one or more WAI-ARIA APG patterns.

    line 116
  9. Distinctive:

    Check each component against its pattern: roles, required states and properties, accessible name, keyboard model, and focus management.

    line 126
  10. Very specific:

    Follow the matching rules in references/APG-PATTERNS.md — in particular, prefer native HTML and never use role="menu" for site navigation.

    line 131
  11. Distinctive:

    Look up those themes in the By theme table and read the A/AA criterion files they list.

    line 146
  12. Distinctive:

    Read a criterion's file before reporting a finding against it, so the verdict matches the actual requirement and its exceptions rather than …

    line 153
  13. Distinctive:

    Before fixing a finding, read the matching fix pattern in references/A11Y-PATTERNS.md.

    line 158
  14. Distinctive:

    When a fix touches a widget's role, states, or keyboard handling, implement it to its APG pattern: open the pattern page linked in …

    line 165
  15. Distinctive:

    Run this after the automated pass, at both viewports, on the parts of the page the automated findings touched:

    line 174

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Accessibility audit

Audits a single page (the URL passed as the argument; ask for it if missing) for accessibility barriers, using two independent automated engines plus live browser inspection, then turns the findings into concrete code fixes.

Get the user's approval before changing any code: the report comes first, and fixes are applied only once the user agrees to them.

Audit every page at two viewports, desktop (at least 1024px wide) and mobile (320px wide, the WCAG 1.4.10 reflow width), because layout and navigation differ between them. On mobile, check that a menu collapsed behind a hamburger button can be opened, operated, and closed by keyboard and screen reader (APG Disclosure pattern).

What "automated" does and doesn't cover: axe-core and Lighthouse reliably catch roughly a third of WCAG failures — missing alt text, unlabeled fields, contrast ratios, missing landmarks, invalid ARIA. They cannot judge whether alt text is meaningful, whether a keyboard flow is usable, or whether reading order makes sense. A 100/100 Lighthouse score is not WCAG conformance. Always pair the automated pass with the manual checklist near the end of this file.

Requirements

  • Node.js 20+ and npm (for the axe-core runner and Lighthouse CLI).
  • A local Chrome, Chromium, or Edge install (the scripts drive it directly; no chromedriver needed).
  • jq — used by the shell scripts for JSON handling.
  • If you have Chrome DevTools MCP or the claude-in-chrome browser tool available, use it too — it gives you live DOM/accessibility-tree inspection the scripts can't (see Live browser inspection).

Everything here runs locally; nothing is uploaded to a third-party service.

How it works

  1. Run Lighthouse (accessibility category) and axe-core against the given URL only — don't follow links to other pages.
  2. If a browser tool is available, inspect the live accessibility tree and exercise the page by keyboard — automated tools miss most of what this step catches.
  3. Map every interactive component to one or more APG patterns and check it against them.
  4. Check the WCAG 2.2 criteria that apply to what's on the page, using the per-criterion files indexed in references/WCAG-CRITERIA.md — this is where the barriers automation can't see get caught.
  5. Cross-reference findings against references/AXE-RULES.md, references/WCAG-CRITERIA.md, and references/APG-PATTERNS.md.
  6. Report findings by severity with file:line locations and concrete fixes, then apply the fixes the user approves.
  7. Re-run the same audit to confirm the fix and check for regressions.

1. Run the automated engines

For an authenticated or user-generated-state page, prefer whatever browser tool is already open at that state over navigating fresh — the scripts always do a clean navigation, so they'll hit a login wall for authenticated content. Use live browser inspection for those pages instead of the scripts.

./scripts/audit.sh https://example.com --viewport desktop --out-dir ./a11y-report
./scripts/audit.sh https://example.com --viewport mobile --out-dir ./a11y-report

First run installs puppeteer-core + axe-core into scripts/node_modules (not committed — already gitignored). This orchestrator:

  • Runs scripts/run-lighthouse.sh (Lighthouse, accessibility-only) and scripts/run-axe.mjs (axe-core) against the page.
  • Writes condensed results (up to 10 failing nodes per rule) to <out-dir>/<slug>.<viewport>.lighthouse.json and <out-dir>/<slug>.<viewport>.axe.json.
  • Prints a summary to stdout (also saved as <slug>.<viewport>.summary.json) — the score and the failing rules ranked by how many nodes fail them (topAxeRules, topLighthouseAudits).

Read the .axe.json / .lighthouse.json files for node-level detail (selectors, HTML snippets, failure summaries) once you know which rules to chase from the summary.

Use run-axe.mjs rather than @axe-core/cli: the CLI's chromedriver dependency fails to install (ERR_REQUIRE_ESM), while run-axe.mjs drives your existing browser through puppeteer-core.

Tool routing

NeedPreferred routeFallback
Accessibility score + audit-level detailscripts/run-lighthouse.shChrome DevTools MCP lighthouse_audit, if available and a fresh navigation is acceptable
Rule-level violations with exact failing nodesscripts/run-axe.mjsaxe DevTools / WAVE browser extension (manual)
Rendered accessibility tree, names/roles/statesChrome DevTools MCP take_snapshot, or claude-in-chrome read_pageManual screen reader pass
Keyboard interactionclaude-in-chrome computer (Tab/Enter/Space/Arrow keys)Manual keyboard testing

2. Live browser inspection (recommended)

Automated engines can't tell you if focus order is logical, if a modal traps keyboard focus correctly, or if an aria-label is actually accurate. When a browser tool is available:

  1. Open the audited URL.
  2. Take an accessibility-tree snapshot; check that interactive elements have sensible names, roles, and states, and that headings/landmarks form a logical outline.
  3. Tab through the whole page. Every interactive element must be reachable, show a visible focus indicator, and activate with Enter/Space. Watch for keyboard traps.
  4. For each composite widget (tabs, menus, comboboxes, dialogs, …), exercise the keyboard model of its APG pattern — arrow keys, Home/End, Escape, focus return — not just Tab (see step 3).
  5. Re-run the automated engines after any fix and repeat the manual pass on the changed area — don't just trust the new score.

If no browser tool is available, do this manually in a real browser and note it in the report as a pending manual check rather than skipping it silently.

3. Map components to APG patterns

Every interactive web component must match, or at least reference, one or more WAI-ARIA APG patterns. Automated engines check that ARIA is valid, not that a widget behaves the way its role promises — the APG pattern is the yardstick for that.

  1. Inventory the interactive components on the page (from the accessibility tree and the source): navigation, menus, dialogs, disclosures, form widgets, tabs, carousels, tables, etc. Plain links and buttons only need listing when they are custom-built (role="button", role="link").
  2. Map each one to its APG pattern(s) by behavior, not by name or look — use the catalog and the component-name table in references/APG-PATTERNS.md. Composite components cite every pattern they combine; components with no direct match cite the closest one and say so.
  3. Check each component against its pattern: roles, required states and properties, accessible name, keyboard model, and focus management.
  4. Classify it as Matches, Deviates (documented and justified, no WCAG failure), or Fails (breaks a WCAG criterion — report it as a finding). A deviation is acceptable; an undocumented or unjustified one is not.

Follow the matching rules in references/APG-PATTERNS.md — in particular, prefer native HTML and never use role="menu" for site navigation.

4. Check the applicable WCAG criteria

references/principles/ holds one file per WCAG 2.2 success criterion: the requirement in plain language, its level, the disabilities it affects, who usually owns the fix (code, design, content), and themes that say what kind of content it applies to. references/WCAG-CRITERIA.md indexes them.

The conformance target is Level A and AA. Report AAA failures only as advisory, and skip 4.1.1 (obsolete).

  1. From the page content and the component inventory, decide which themes are present — e.g. forms for any input, gestures for touch/drag/pointer interactions, keyboards for anything interactive, sensory for media, color and motion, zoom-readability for text and layout, wording for copy, code-labels for names and structure, whole for site-wide consistency.
  2. Look up those themes in the By theme table and read the A/AA criterion files they list. Each criterion either already has evidence from the engines or the live pass, or needs a manual check now.
  3. Mark each applicable criterion Pass, Fail (report it as a finding), N/A (the content it governs isn't on the page — say why), or Not verified (needs a tool or a human you don't have, e.g. a screen reader pass, captions accuracy, or other pages for whole criteria). Never let a criterion go silently unchecked.

Read a criterion's file before reporting a finding against it, so the verdict matches the actual requirement and its exceptions rather than a paraphrase.

Fixing common issues

Before fixing a finding, read the matching fix pattern in references/A11Y-PATTERNS.md. It covers missing alt text (image-alt), color contrast (color-contrast), keyboard navigation and focus, form labels, error handling, skip links, modal focus traps, ARIA tabs, live regions, and repeated link text. For a rule-by-rule fix table that matches the scripts' JSON output, see references/AXE-RULES.md.

When a fix touches a widget's role, states, or keyboard handling, implement it to its APG pattern: open the pattern page linked in references/APG-PATTERNS.md and follow its keyboard table and example code rather than inventing a new interaction model.

Contrast thresholds (WCAG 1.4.3 / 1.4.11): 4.5:1 for normal text, 3:1 for large text (≥ 24px or ≥ 18.66px bold) and for UI components.

Manual testing checklist

Run this after the automated pass, at both viewports, on the parts of the page the automated findings touched:

  • Keyboard: Tab through the whole page/flow; Enter/Space activate controls; no traps.
  • APG patterns: Each interactive component is mapped to one or more APG patterns, and its keyboard model matches them (or the deviation is documented).
  • Screen reader: Spot-check with VoiceOver (Mac), NVDA (Windows), or TalkBack (Android).
  • Zoom: Content and functionality usable at 200% zoom.
  • Reduced motion: Respects prefers-reduced-motion: reduce.
  • Focus order: Matches visual/logical order; focused elements aren't hidden by sticky headers/footers (WCAG 2.4.11).
  • Target size: Interactive elements meet the 24×24px minimum (WCAG 2.5.8).
  • WCAG criteria: Every A/AA criterion for the themes on the page is marked Pass, Fail, N/A, or Not verified (step 4).

Screen reader shortcut reference: references/A11Y-PATTERNS.md#screen-reader-commands.

Reporting findings

Structure the report by severity, referencing the rule ID so it's traceable back to the scripts' raw JSON — APG: <pattern> for findings from the pattern check, or WCAG <code> for findings from the criteria check. Every finding names the WCAG criteria it fails (code and name), takes its Impact from the criterion's affected disabilities, and notes its owner when the fix isn't (only) code — a design or content change. Include the component inventory from step 3 and the criteria coverage from step 4:

## Accessibility audit — <url>

### Evidence

| Lighthouse a11y score | axe violations | Source |
|------------------------|-----------------|--------|
| 82                     | 6               | scripts/audit.sh |

### Component inventory (APG)

| Component     | Location                          | APG pattern(s)              | Conformance |  Notes                                    |
|---------------|-----------------------------------|-----------------------------|-------------|-------------------------------------------|
| Main nav      | `src/components/Header.tsx:22`    | Disclosure, Landmarks, Link | ❌ Fails     | Uses `role="menubar"` — see Critical      |
| Language menu | `src/components/LangSwitch.tsx:8` | Menu Button + Menu          | ⚠️ Deviates  | No type-ahead (accepted: 3 items only)    |

### Critical (fix immediately)

- **[image-alt]** Logo `<img>` has no alt text. `src/components/Header.tsx:14`
    - **WCAG:** 1.1.1 Non-text Content (A).
    - **Impact:** Screen reader users (visual, cognitive) hear "image" with no context.
    - **Evidence:** axe-core violation, selector `header img.logo`.
    - **Fix:** `<img src="logo.svg" alt="Acme Inc.">`
- **[APG: Disclosure]** Main navigation uses `role="menubar"`/`menuitem` but only supports Tab, so arrow keys do
  nothing and screen readers announce an application menu. `src/components/Header.tsx:22`
    - **WCAG:** 4.1.2 Name, Role, Value (A); 2.1.1 Keyboard (A).
    - **Impact:** Keyboard and screen reader users get a menu interaction model the component doesn't implement.
    - **Evidence:** Live keyboard pass; accessibility tree shows `menubar`.
    - **Fix:** Drop the menu roles; use `<nav aria-label="Main">` with disclosure buttons (`aria-expanded`) for
      submenus — [APG Disclosure navigation](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/).

### Serious / Moderate / Minor

- **[WCAG 1.4.1]** Required fields are marked only by red label color. `src/components/SignupForm.tsx:31`
    - **WCAG:** 1.4.1 Use of Color (A). **Owner:** design.
    - ...

### Advisory (AAA)

...

### WCAG criteria coverage (A/AA)

| Themes present               | Pass | Fail                       | N/A                                   | Not verified                            |
|------------------------------|------|----------------------------|---------------------------------------|-----------------------------------------|
| forms, keyboards, sensory, … | 24   | 1.1.1, 1.4.1, 2.1.1, 4.1.2 | 1.2.x (no media), 2.5.1 (no gestures) | 3.2.3, 3.2.4, 3.2.6 (needs other pages) |

### Manual checks

- [x] Keyboard pass completed — no traps found.
- [ ] Screen reader pass pending.

### Verification

- Re-ran `scripts/audit.sh` after fixes: Lighthouse 82 → 100, axe violations 6 → 0.

Severity ordering: Critical (blocks access entirely — missing labels/alt/names, keyboard traps) → Serious (major barrier — contrast, missing landmarks/lang, broken heading structure) → Moderate (real but workaroundable) → Minor. See references/AXE-RULES.md for the full per-rule breakdown, and use axe-core's own impact field on each violation when it disagrees with the table — it's computed per-instance and is the more precise signal.

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.