a11y
Skill1 starsChanged 5 months agoMITView on GitHub
Audit accessibility (WCAG) compliance in source code and optionally against live URLs
11 other projects use a version of this.
Adopted by
Most recently taken up by
- Buddhilive/buddhi-clitheir own version, first seen Nov 1, 2026
- gbvillarinho/react-design-skillstheir own version, first seen Oct 20, 2026
- pengGgxp/skillstheir own version, first seen Oct 11, 2026
- BeyondTheProtocol/polaristheir own version, first seen Sep 25, 2026
- Pradnyeshp/Claude-Skillstheir own version, first seen Jul 6, 2026
- ariadoss/superskillstheir own version, first seen Jun 21, 2026
Used with
Projects with it also use verify.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Microsoft AzureSkillverify
End-to-end app testing pipeline for browser-based web apps on cloud browsers via Azure Playwright Workspaces: verify the live app, author tests for working flows, heal failing tests, then re-run with video and produce one consolidated report. Three phases (app verification, test authoring, test healing) plus a scoped final sanity run; each phase emits a sub-report. Use when asked to "verify my app", "make sure my app works and has good test coverage", "do a full QA pass", "add tests where I'm missing coverage", "fix failing tests and add new ones", "smoke test before deploy", "QA my deployment", or any combined verify-and-test ask. Requires Azure CLI (`az login`) and a Playwright Workspace resource ID — bootstraps configs on first invocation. Browser-based web apps with Playwright only — not for unit/API tests, native mobile/desktop, load/perf, or full accessibility audits.
Also in 3 projects that use this
Other versions11 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 11
- BeyondTheProtocol/polaris★ 47same name
- bmarshall511/forexflow★ 14same name
- ariadoss/superskills★ 12same name
- launch52-ai/flutter-template★ 2same name
- Pradnyeshp/Claude-Skills★ 2same name
- Buddhilive/buddhi-cli★ 1same name
- pengGgxp/skills★ 1same name
- CorentinGC/claude-skills★ 0same name
- gbvillarinho/react-design-skills★ 0same name
- Nadav011/apex-skills★ 0same name
1 more not listed
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.
In this repository13 other files it gives its agents.
- cohesionSkill
- couplingSkill
- designSkill
- driftSkill
- full-sweepSkill
- onboardSkill
- perfSkill
- privacySkill
- seoSkill
- sessionSkill
- shipSkill
- thatsweirdSkill
- walkthroughSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
19 rules. 0 are common, 6 are distinctive, and 13 are very specific to this project.
0
Common
Most of the 9 edited versions we read keep these.
6
Distinctive
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 37
No args: audit current working directory
- Distinctive: line 68
Read CLAUDE.md for any project-specific accessibility notes or conventions
- Distinctive: line 73
Search layouts and page templates for:
- Very specific: line 76
If there are multiple <nav> elements, does each have an aria-label or aria-labelledby to distinguish them?
- Distinctive: line 85
Do headings follow a logical order (no skipping from h1 to h3)?
- Distinctive: line 99
Search all components/templates for interactive elements:
- Very specific: line 116
Search for <form>, <input>, <select>, <textarea>:
- Very specific: line 117
Every input must have an associated <label> (via for/htmlFor attribute matching id, or wrapping the input).
- Very specific: line 128
Every <img> must have an alt attribute.
- Very specific: line 137
If the project has <video> or <audio> elements:
- Very specific: line 167
Check for CSS animations or transitions without prefers-reduced-motion media query support.
- Very specific: line 203
When --live is passed, use WebFetch to check each page's rendered HTML for:
- Very specific: line 272
Add lang="en" to <html> if missing
- Very specific: line 273
Add alt="" to images that are clearly decorative (inside links with text, CSS background replacements).
- Very specific: line 274
Add aria-hidden="true" to decorative SVG icons
- Very specific: line 275
Remove role="button" from <button> elements (redundant)
- Very specific: line 277
Add rel="noopener" to target="_blank" links if missing
- Distinctive: line 297
Don't penalize what doesn't exist: No forms = no form audit. No media = no media audit.
- Very specific: line 304
After completing this skill, append a log entry to ~/.claude/skill-log.md under the Run Log table.
“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Accessibility Audit
Scan a project's source code for WCAG 2.1 accessibility violations. Optionally check live URLs for rendered accessibility issues. Can auto-fix safe categories.
Sample output
A successful run produces something like:
## Accessibility Audit — marketing-site
Score: 76/100 (C)
Stack: Next.js 16
### CRITICAL (blocks entire user groups)
1. Keyboard accessibility — src/components/NavMenu.tsx:42 — onClick handler on <div> with no tabIndex or onKeyDown. Keyboard users can't open the menu. Fix: change to <button>.
### SERIOUS
1. Forms — src/app/contact/page.tsx:18 — <input name="email"> has placeholder but no <label>. Fix: wrap in <label> or add aria-label.
2. Images — src/components/Hero.tsx:24 — <img src="/hero.jpg"> missing alt attribute.
### MODERATE
1. Heading hierarchy — src/app/about/page.tsx — page jumps from h1 to h3, skipping h2.
### Summary
- 1 critical, 2 serious, 1 moderate
- Top priority: NavMenu keyboard accessibility (blocks every keyboard user)Arguments
The user may specify:
- No args: audit current working directory
- A project name or path (e.g.,
myapp,marketing-site) --fix: auto-fix safe categories (missing alt placeholders, missing ARIA labels on obvious elements, lang attribute, etc.)--live: also fetch live URLs and audit the rendered HTML--scope <path>: limit to a specific directory or file
Parse the argument string. Examples:
/a11y-- audit current project, source only/a11y myapp-- audit myapp source/a11y myapp --live-- audit myapp source + live URL/a11y --fix-- audit and auto-fix current project/a11y --scope src/components-- audit only components directory
Project Registry
| Alias | Path | Live URL |
myapp | (add your projects here) | (add your projects here) |
Process
Step 0: Detect the project
- Resolve path from alias table or cwd
- Detect the stack (Next.js, Astro, Flask/Jinja, static HTML, React Native)
- Identify template/component directories where HTML is generated:
- Next.js:
app/,src/app/,src/components/,components/ - Astro:
src/pages/,src/layouts/,src/components/ - Flask/Jinja:
src/templates/,templates/,src/**/templates/ - Static HTML: all
.htmlfiles in root and subdirectories - React Native / Expo: skip this audit entirely -- native apps use a different accessibility model (accessibilityLabel, accessibilityRole, etc.). Note this and suggest a native-specific check instead.
- Next.js:
- Read
CLAUDE.mdfor any project-specific accessibility notes or conventions
Step 1: Structural / Semantic HTML
1a. Landmark regions
Search layouts and page templates for:
- Does the page have a
<main>element? (exactly one per page) - Does the page have a
<nav>element for primary navigation? - If there are multiple
<nav>elements, does each have anaria-labeloraria-labelledbyto distinguish them? - Is there a
<header>and<footer>at the page level? - Are
<section>elements used with headings oraria-label(a<section>without an accessible name is meaningless to screen readers)?
Flag: Missing <main>, navigation without labels when multiple exist, <section> without accessible name.
1b. Heading hierarchy
For each page/template:
- Is there exactly one
<h1>? - Do headings follow a logical order (no skipping from h1 to h3)?
- Are headings used for structure, not just styling? (A
<h3>used because it "looks right" instead of using CSS is a smell)
Flag: Missing h1, skipped heading levels, multiple h1s on a single page.
1c. Lists
- Are groups of related links wrapped in
<ul>or<ol>, not just stacked<a>tags with<br>between them? - Are navigation menus using list markup?
Flag: Navigation links not in list elements.
Step 2: Interactive Elements
2a. Keyboard accessibility
Search all components/templates for interactive elements:
- Click handlers on non-interactive elements:
onClick/@click/on:clickon<div>,<span>,<td>,<img>, or other non-interactive elements withoutroleandtabIndex. These are invisible to keyboard users. - Missing keyboard equivalents:
onClickwithout correspondingonKeyDown/onKeyUphandler on non-button/non-link elements. - Positive tabindex:
tabindexvalues greater than 0 break natural tab order.tabindex="0"(add to tab order) andtabindex="-1"(programmatic focus only) are fine. - Autofocus abuse:
autoFocuson elements that aren't the primary action on the page (disorienting for screen reader users).
Flag: Click handlers on divs/spans without role+tabIndex, positive tabindex values.
2b. Buttons and links
<a>tags withouthref(or withhref="#"orhref="javascript:void(0)") -- these should be<button>elements.<button>elements without visible text oraria-label. Icon-only buttons need labels.- Links that open in new tabs (
target="_blank") without indicating this to the user (addaria-labelsuffix or visible indicator). Also check forrel="noopener". - Empty links:
<a href="..."></a>with no text content or aria-label.
Flag: Fake links (href="#"), unlabeled icon buttons, empty links, new-tab links without indication.
2c. Forms
Search for <form>, <input>, <select>, <textarea>:
- Every input must have an associated
<label>(viafor/htmlForattribute matchingid, or wrapping the input).placeholderis NOT a substitute for a label. - Required fields should have
aria-required="true"or therequiredattribute. - Error messages should be associated with their input via
aria-describedby. - Form groups (e.g., radio buttons) should use
<fieldset>+<legend>. - Submit buttons should have clear text (not just "Submit" -- what are you submitting?).
Flag: Inputs without labels, placeholder-only inputs, unassociated error messages.
Step 3: Images and Media
3a. Images
- Every
<img>must have analtattribute. - Decorative images should have
alt=""(empty alt, not missing alt). - Informative images should have descriptive alt text, not filenames (
alt="IMG_2847.jpg") or generic text (alt="image",alt="photo",alt="icon"). - CSS background images that convey information need an alternative (text or aria-label on the container).
- SVG icons used inline: should have
aria-hidden="true"if decorative, orrole="img"+aria-labelif meaningful.
Flag: Missing alt, filename alt text, generic alt text, meaningful SVGs without labels.
3b. Media
If the project has <video> or <audio> elements:
- Videos should have captions or a transcript
- Audio should have a transcript
- Media players should be keyboard-operable
Flag: Video without captions/transcript, audio without transcript.
Step 4: Color and Visual
4a. Color contrast
This is hard to check from source alone, but look for:
- Inline styles or CSS with text color + background color combinations that can be evaluated. Common failures:
- Light gray text on white (
#999 on #fff= 2.8:1, needs 4.5:1) - White text on bright colors (yellow, light green, light blue backgrounds)
- Light gray text on white (
- Tailwind classes: check for low-contrast combinations (e.g.,
text-gray-400 bg-white,text-white bg-yellow-300) - CSS custom properties: if the project defines color tokens/variables, check them against WCAG AA minimums:
- Normal text: 4.5:1 ratio minimum
- Large text (18px+ bold or 24px+): 3:1 ratio minimum
- UI components and graphical objects: 3:1 ratio minimum
Flag: Detectable low-contrast combinations. Note that full contrast audit requires --live mode.
4b. Color as sole indicator
- Links distinguished from body text only by color (no underline, no other visual indicator). Links within body text must have a non-color indicator.
- Form errors indicated only by turning the border red. Must also have text or icon.
- Status indicators (success/error/warning) using only color. Must also have text or icon.
Flag: Color-only link differentiation in body text, color-only error states.
4c. Motion and animation
- Check for CSS animations or transitions without
prefers-reduced-motionmedia query support. - Flag any
animationproperty used without a corresponding@media (prefers-reduced-motion: reduce)rule somewhere in the project's CSS. - Autoplay video or animated content without pause controls.
Flag: Animations without reduced-motion support, autoplay without controls.
Step 5: ARIA Usage
5a. ARIA done right
aria-hidden="true"on elements that contain focusable children (traps keyboard users in invisible elements).roleattribute with an invalid value.aria-labelledbyoraria-describedbypointing to anidthat doesn't exist in the same page.- Redundant ARIA:
role="button"on a<button>,role="link"on an<a>,role="navigation"on a<nav>. These are already implicit. aria-labelon elements that don't support it (e.g.,<div>without a role,<span>).
Flag: Broken ARIA references, ARIA on focusable hidden elements, redundant roles.
5b. Dynamic content
- Modals/dialogs: should have
role="dialog",aria-modal="true", focus trap, and return focus on close. - Toast/notification components: should use
role="alert"oraria-live="polite". - Loading states: should use
aria-busy="true"on the container, or a live region announcing the state change. - Content that updates without page reload: should use
aria-liveregions.
Flag: Modals without dialog role/focus management, dynamic content without live regions.
Step 6: Document-Level
<html>haslangattribute (e.g.,lang="en")- Page
<title>is unique and descriptive per page (not just the site name everywhere) - Skip-to-content link exists (a visually hidden link at the top of the page that jumps to
<main>) - Viewport meta doesn't disable zoom:
user-scalable=noormaximum-scale=1are violations
Flag: Missing lang, missing/duplicate titles, missing skip link, zoom disabled.
Live Check (--live flag)
When --live is passed, use WebFetch to check each page's rendered HTML for:
- Rendered heading hierarchy -- does the final HTML have correct h1-h6 order?
- Rendered landmarks -- are
<main>,<nav>,<header>,<footer>present in output? - Rendered form labels -- do inputs have associated labels in the final DOM?
- Contrast estimation -- parse inline styles and class-based colors in the rendered output
- ARIA reference integrity -- do all
aria-labelledby/aria-describedbyIDs resolve?
Compare live results against source findings. Flag discrepancies (SSR issues, hydration bugs that break accessibility).
Scoring
Max score: 100 points. Weighted by impact:
| Category | Weight | Rationale |
| Keyboard accessibility (2a) | 20 | Complete blocker for keyboard/switch users |
| Forms (2c) | 15 | Blocks task completion |
| Images and alt text (3a) | 15 | Core screen reader experience |
| Heading hierarchy (1b) | 10 | Navigation and comprehension |
| Landmarks (1a) | 10 | Screen reader navigation |
| Buttons and links (2b) | 10 | Core interaction |
| Document-level (Step 6) | 8 | Foundation |
| ARIA usage (5a, 5b) | 5 | Correctness |
| Color/contrast (4a, 4b) | 5 | Partial check from source (full check needs --live) |
| Motion (4c) | 2 | Important but narrower impact |
Formula: score = (earned_points / applicable_points) * 100
Skip checks that don't apply (no forms = skip form checks, no images = skip image checks).
Grade scale:
| Score | Grade | Meaning |
| 90-100 | A | Solid. Minor polish only. |
| 80-89 | B | Good foundation, some gaps. |
| 70-79 | C | Usable but excluding people. Fix the keyboard and form issues. |
| 60-69 | D | Significant barriers. Needs dedicated work. |
| 0-59 | F | Major accessibility failures. Prioritize before shipping. |
Output Format
## Accessibility Audit -- [project name]
**Score:** [score]/100 ([grade])
**Stack:** [detected stack]
**WCAG Level:** AA (target)
### CRITICAL (blocks entire user groups)
1. **[Category]** [file:line] -- [what's wrong] -- [how to fix]
### SERIOUS (degrades experience significantly)
1. **[Category]** [file:line] -- [what's wrong] -- [how to fix]
### MODERATE (should fix)
1. **[Category]** [file:line] -- [what's wrong] -- [how to fix]
### MINOR (polish)
1. **[Category]** [file:line] -- [what's wrong] -- [how to fix]
### Summary
- [X] critical, [Y] serious, [Z] moderate, [W] minor issues
- Top priority: [the one thing to fix first]Fix Mode (--fix flag)
Safe to auto-fix:
- Add
lang="en"to<html>if missing - Add
alt=""to images that are clearly decorative (inside links with text, CSS background replacements). Addalt="TODO: describe this image"to content images missing alt. - Add
aria-hidden="true"to decorative SVG icons - Remove
role="button"from<button>elements (redundant) - Remove
role="link"from<a>elements (redundant) - Add
rel="noopener"totarget="_blank"links if missing
Requires confirmation:
- Adding
aria-labelto icon buttons (needs the right label text) - Adding skip-to-content link (needs to match page structure)
- Wrapping inputs with
<label>(needs to not break layout) - Adding
prefers-reduced-motionCSS (needs to know which animations to disable)
Never auto-fix:
- Color contrast (requires design decisions)
- Focus management in modals (requires understanding the component logic)
- Heading hierarchy (restructuring headings can break design intent)
- ARIA live regions (requires understanding what content updates dynamically)
Rules
- React Native / Expo projects: Skip this audit. Native accessibility uses
accessibilityLabel,accessibilityRole,accessibilityState, etc. -- a completely different model. Note this and stop. - Don't flag framework internals. Next.js
<Head>, Astro<Layout>, Jinja{% block %}are structural. Check what they render, not the templating syntax. - Stack-aware fixes. In JSX it's
htmlFor, in HTML it'sfor. In JSX it'stabIndex, in HTML it'stabindex. Get it right. - Severity by impact. A missing skip link is moderate. A click handler on a div with no keyboard equivalent is critical -- it's a complete blocker for keyboard users.
- Don't penalize what doesn't exist. No forms = no form audit. No media = no media audit.
- Be specific about fixes. "Add alt text" is useless. "Add
alt=\"<describe the image content>\"to<img>atsrc/templates/<file>.html:<line>" is useful. - Prefer semantic HTML over ARIA. The fix for a clickable div is almost always "make it a button," not "add role=button and tabindex=0 and onKeyDown."
Skill Run Logging
After completing this skill, append a log entry to ~/.claude/skill-log.md under the Run Log table. New entries at the top (most recent first).
Format: | YYYY-MM-DD | /skill-name | target (details) | one-line result |
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
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.

