Accessibility Audit Skill
How this skill behaves (read first)
This is an evaluative skill — it reviews existing work against a standard (WCAG), it doesn't generate UI. Flagging is safe, so it auto-runs and is designed to be called as a validation step by generative skills as well as invoked directly.
It owns the accessibility concern in this repo. Generative skills hand off to it (e.g. ux-login-signup, ux-pricing), and the heuristics audit (ux-heuristics-audit) deliberately defers contrast / keyboard / screen-reader specifics here rather than duplicating them. When invoked, do the full a11y pass; don't assume another skill covered it.
Scope discipline. When invoked directly (the user named this audit), review only this concern — don't pull in sibling audits. It runs alongside other lenses only when an orchestrator (ux-design-review) or a generative skill calls it under docs/orchestration-policy.md, where it sits in Tier B — offered (and narrowed to usage when a design system is in play). Explicit scope always wins.
What this skill changes vs. default behavior
By default, accessibility feedback tends to be partial and vague — a few obvious call-outs ("add alt text", "check contrast") with no standard, no severity, and no systematic sweep. This skill forces four things:
- Every finding cites the WCAG criterion and level it violates — not a vague suggestion.
- Every finding gets a severity based on how completely it blocks access — so the list is prioritized.
- Every finding has a concrete fix — the specific markup/design change.
- The audit is systematic — it sweeps all six categories below, so issues outside the obvious ones (focus order, heading hierarchy, table semantics, motion) actually get caught.
WCAG foundations
POUR principles — every audit item maps to one of these four:
- Perceivable — content must be detectable via at least one sense (sight, hearing, etc.)
- Operable — all interactions must work without a mouse (keyboard, switch, voice)
- Understandable — content and UI must be clear and predictable
- Robust — content must work across browsers, devices, and assistive technologies
Compliance levels:
- Level A — bare minimum; missing these creates complete barriers (e.g. no alt text, no keyboard access).
- Level AA — the legal standard most organizations must meet; the default target for every audit.
- Level AAA — aspirational; apply selectively where it adds high value.
Default audit target: WCAG 2.1 Level AA.
Audit checklist
Work through every category — a partial sweep is the main way real issues get missed. Flag each violation with WCAG criterion, severity (see model below), and a fix.
1. Color & Contrast
| Check |
Requirement |
Notes |
| Normal text vs background |
≥ 4.5:1 (AA) / 7:1 (AAA) |
Applies to all text in UI: buttons, labels, cards, nav |
| Large text (≥ 18pt or ≥ 14pt bold) |
≥ 3:1 |
|
| Icons (informational or interactive) |
≥ 3:1 |
Decorative icons exempt |
| Input borders vs surrounding background |
≥ 3:1 |
Including focus indicators |
| Text over images |
≥ 4.5:1 between text and the portion of image behind it |
Use semi-transparent overlay if needed |
| Selection states |
Same ratios as regular text |
|
| Disabled elements |
Exempt from contrast rules |
Must still be recognizable as inactive |
| Logo text |
Exempt |
But good practice to maintain contrast anyway |
| Color as sole differentiator |
❌ Never |
Always pair color with icon, pattern, label, or text |
| Stark contrast (pure black on white) |
Discouraged |
Use #333 on #F8F8F8 — exceeds AA while reducing eye strain |
Don't rely on color alone: error states need an icon + text, not just red. Charts need patterns or labels, not just color.
2. Typography & Text
| Check |
Requirement |
| Base body font size |
≥ 16px |
| Line length |
45–75 characters (including spaces) |
| Text alignment |
Follows reading direction (LTR → left-align; RTL → right-align) |
| Headings visually distinct |
Larger size, bold weight, or color difference from body text |
One <h1> per page |
Page title only |
| Heading hierarchy |
No skipped levels (h1 → h2 → h3, never h1 → h3) |
| Semantic heading tags |
Use <h1>–<h6>, not styled <div> or <p> |
| Language |
Plain language, secondary-education reading level |
| Idioms & figures of speech |
Avoid — confuse screen readers and non-native speakers |
| Typeface |
Clear letterform distinctions (0 vs O, 1 vs l vs I); large x-height |
3. Forms
| Check |
Requirement |
| Keyboard access |
Every field, dropdown, checkbox, radio, button navigable via Tab / Shift+Tab / Enter / arrows |
| Focus indicators |
Visible on every focused element — never remove browser default without replacing |
| Layout |
Single-column preferred; multi-column increases cognitive load and screen-reader confusion |
| Input boundaries |
Visible borders or backgrounds — never borderless inputs |
| Labels |
Outside the field, not placeholder-only; min 16px; 4.5:1 contrast |
| Placeholder text |
Supplemental only — disappears on input, so never the sole label |
| Autocomplete |
Implement for name, email, phone, address, payment (HTML autocomplete attribute) |
| Error states |
Multiple cues: icon + bold border + field-specific message. Never color alone |
| Error placement |
Adjacent to the offending field + aria-describedby linking field to error |
| Error summary |
At top of form on submit failure, with anchor links to each problem field |
| Authentication |
No text-based CAPTCHA — use magic links, OTP, passkeys, or biometrics. Support paste in password fields |
| Mobile one-handed use |
Center CTAs in lower-middle zone; avoid right-edge-only button placement |
4. Links & Navigation
| Check |
Requirement |
| Link labels |
Descriptive, specific — "Download pricing guide" not "Click here" or "Read more" |
| New-window links |
Warn users in link text or aria-label: "opens in new tab" |
| File links |
State type + size: "Annual Report (PDF, 2.5 MB)" |
| Raw URLs as link text |
❌ Never — screen readers read character by character |
| Link recognizability |
Underline + color (not color alone) |
| Focus state |
Visible, distinctive focus ring on every link and interactive element |
href attribute |
Required on all <a> tags — <div> with click handler is not a link |
| Voice/tone |
Link text should match the product's voice, but always prioritize clarity |
| Help links |
Consistently placed (footer, header utility nav, or persistent help icon) |
5. Images & Multimedia
| Check |
Requirement |
| Informational images |
alt attribute with meaningful description |
| Decorative images |
alt="" (null) — tells screen readers to skip |
| Images containing text |
Alt text = the exact text in the image |
| Autoplay |
❌ Disabled by default — user must initiate playback |
| Media controls |
Play/pause/stop/rewind/volume/mute/captions — keyboard accessible, sufficient size and contrast |
| Video captions |
Required for all pre-recorded video with audio |
| Audio transcripts |
Required for all audio-only content |
| Flashing/strobing content |
❌ No content flashing > 3 Hz or red flashing at any rate |
| Animations (GIF, SVG, CSS) |
No more than 5 light-dark stripe pairs; provide a way to pause/stop |
| Icons |
Pair with text labels; informational icons need aria-label or title |
| Swipe gestures |
Support both directions or provide an alternate tap target |
6. Tables & Lists
| Check |
Requirement |
| Data tables |
Use <table> element — never use tables for layout |
| Table caption |
<caption> immediately after <table> opening tag |
| Header cells |
<th> with scope="col" or scope="row" — never empty |
| Complex tables |
Avoid merged cells and multi-level headers; split into simpler tables if needed |
| Cell widths |
Use % not px — allows browser reflow; never set cell height manually |
| Lists |
Use <ul>, <ol>, or <dl> appropriately — not styled <div> rows |
| Unordered lists |
For items where order doesn't matter |
| Ordered lists |
For sequential steps, rankings, instructions |
| Description lists |
<dl> / <dt> / <dd> for glossaries, FAQs, key-value metadata |
Severity rating
Rate each finding by how completely it blocks access and which WCAG level it fails:
| Severity |
Meaning |
| Critical |
Blocks access entirely for some users. Usually a Level A failure — no keyboard access, no alt text on informational images, missing captions, a keyboard trap. Fix before ship. |
| Major |
Significant friction; users can sometimes work around it but shouldn't have to. Usually a Level AA failure — contrast below 4.5:1, placeholder-as-label, color-only error states, missing focus indicators. |
| Minor |
Noticeable but low-impact, or a best-practice / AAA improvement — slightly short line length, stark pure-black text, a non-ideal but functional label. |
When in doubt, rate by the user impact (does it block a task or merely add friction?), not by how easy the fix is.
Audit output format
## Accessibility Audit — [Component / Screen Name]
Context: [platform · WCAG target (default AA) · design or code]
### Critical (blocks access entirely)
- [Issue]: [what's wrong] → [fix] — WCAG [X.X.X]
### Major (significant friction)
- [Issue]: [what's wrong] → [fix] — WCAG [X.X.X]
### Minor (best practice / AAA)
- [Issue]: [what's wrong] → [fix] — WCAG [X.X.X]
### Passed ✓
- [what's already working]
Always end with a one-line summary stating the overall WCAG AA compliance status and the top fixes that would get it there.
How to run a good audit
- Establish context. Platform (web/mobile/native), target level (AA by default — only go AAA if asked), and whether you're auditing a design or live code (some checks, like keyboard order and
aria-*, only apply to code).
- Sweep all six categories. The value of this skill over a default review is completeness — don't stop at contrast and alt text.
- Rate by barrier, not by effort. A one-line
alt fix can still be Critical.
- Be specific in fixes. Give the exact change (markup, attribute, ratio, or design adjustment), not "make it accessible."
- Note tooling limits. Automated scanners catch only ~30–40% of issues — manual review of focus order, alt-text quality, and reading order still matters.
Recommended tools
For automated scanning (catches ~30–40% of issues):
- WAVE (browser extension) — overlays visual indicators, references violated WCAG criteria
- axe DevTools (Chrome extension) — accurate, dev-friendly; powered by axe-core
- Google Lighthouse (Chrome DevTools → Lighthouse tab) — accessibility + SEO + performance in one pass
For contrast checking in design:
- Able (Figma plugin) — contrast checker + color-blindness simulator
- Stark (Figma / Sketch / Adobe XD) — contrast, vision simulator, focus order, alt-text annotations
- WCAG Color Contrast Checker (Chrome extension) — real-time ratio checking in browser
For screen-reader testing:
- VoiceOver (macOS/iOS, built-in) — navigate with
VO + arrow keys
- NV Access / NVDA (Windows, free) — most widely used Windows screen reader
For seizure risk:
- PEAT (downloadable) — analyzes video/animation for photosensitive epilepsy triggers
- Harding Test — online paid service for broadcast/video content
Common do/don't patterns
| ❌ Don't |
✅ Do |
| Use red text alone for errors |
Red border + warning icon + descriptive message |
<a>Click here</a> |
<a>Download the onboarding guide (PDF, 1.2 MB)</a> |
<img src="chart.png"> (no alt) |
<img src="chart.png" alt="Bar chart showing Q3 revenue by region"> |
| Decorative image with alt text |
<img src="bg-swoosh.svg" alt=""> |
Pure black #000 on pure white #FFF |
Dark grey #333 on off-white #F8F8F8 |
| Placeholder as the only label |
Persistent label above the field + optional placeholder |
Jump from <h1> to <h3> |
Always use <h1> → <h2> → <h3> in order |
| Table for page layout |
CSS Grid or Flexbox for layout; <table> for data only |
| Autoplay video |
Controls visible at top; user initiates playback |
| Color-only chart legend |
Add patterns, shapes, or data labels alongside color |
| Report only the obvious issues |
Sweep all six categories; rate by barrier; cite the criterion |
Source lessons (Uxcel)
1---2name: ux-accessibility-audit3description: Run a structured WCAG 2.1 AA accessibility audit on a design, screen, component, or page. Produces a prioritized issue list — each finding cites the violated WCAG criterion, a severity rating (Critical/Major/Minor), and a concrete fix. Use when auditing for a11y compliance or as a validation step after generating UI.4license: MIT5---67# Accessibility Audit Skill8910## How this skill behaves (read first)1112This is an **evaluative** skill — it reviews existing work against a standard (WCAG), it doesn't generate UI. Flagging is safe, so it **auto-runs** and is designed to be **called as a validation step** by generative skills as well as invoked directly.1314It **owns the accessibility concern** in this repo. Generative skills hand off to it (e.g. `ux-login-signup`, `ux-pricing`), and the **heuristics audit** (`ux-heuristics-audit`) deliberately defers contrast / keyboard / screen-reader specifics here rather than duplicating them. When invoked, do the full a11y pass; don't assume another skill covered it.1516**Scope discipline.** When invoked directly (the user named this audit), review **only this concern** — don't pull in sibling audits. It runs alongside other lenses only when an orchestrator (`ux-design-review`) or a generative skill calls it under `docs/orchestration-policy.md`, where it sits in **Tier B — offered (and narrowed to usage when a design system is in play)**. Explicit scope always wins.1718---1920## What this skill changes vs. default behavior2122By default, accessibility feedback tends to be partial and vague — a few obvious call-outs ("add alt text", "check contrast") with no standard, no severity, and no systematic sweep. This skill forces four things:23241. **Every finding cites the WCAG criterion and level** it violates — not a vague suggestion.252. **Every finding gets a severity** based on how completely it blocks access — so the list is prioritized.263. **Every finding has a concrete fix** — the specific markup/design change.274. **The audit is systematic** — it sweeps all six categories below, so issues outside the obvious ones (focus order, heading hierarchy, table semantics, motion) actually get caught.2829---3031## WCAG foundations3233**POUR principles** — every audit item maps to one of these four:3435- **Perceivable** — content must be detectable via at least one sense (sight, hearing, etc.)36- **Operable** — all interactions must work without a mouse (keyboard, switch, voice)37- **Understandable** — content and UI must be clear and predictable38- **Robust** — content must work across browsers, devices, and assistive technologies3940**Compliance levels:**4142- **Level A** — bare minimum; missing these creates complete barriers (e.g. no alt text, no keyboard access).43- **Level AA** — the legal standard most organizations must meet; the **default target for every audit**.44- **Level AAA** — aspirational; apply selectively where it adds high value.4546Default audit target: **WCAG 2.1 Level AA**.4748---4950## Audit checklist5152Work through every category — a partial sweep is the main way real issues get missed. Flag each violation with **WCAG criterion**, **severity** (see model below), and a **fix**.5354### 1. Color & Contrast5556| Check | Requirement | Notes |57|---|---|---|58| Normal text vs background | ≥ 4.5:1 (AA) / 7:1 (AAA) | Applies to all text in UI: buttons, labels, cards, nav |59| Large text (≥ 18pt or ≥ 14pt bold) | ≥ 3:1 | |60| Icons (informational or interactive) | ≥ 3:1 | Decorative icons exempt |61| Input borders vs surrounding background | ≥ 3:1 | Including focus indicators |62| Text over images | ≥ 4.5:1 between text and the portion of image behind it | Use semi-transparent overlay if needed |63| Selection states | Same ratios as regular text | |64| Disabled elements | Exempt from contrast rules | Must still be recognizable as inactive |65| Logo text | Exempt | But good practice to maintain contrast anyway |66| Color as sole differentiator | ❌ Never | Always pair color with icon, pattern, label, or text |67| Stark contrast (pure black on white) | Discouraged | Use #333 on #F8F8F8 — exceeds AA while reducing eye strain |6869**Don't rely on color alone**: error states need an icon + text, not just red. Charts need patterns or labels, not just color.7071---7273### 2. Typography & Text7475| Check | Requirement |76|---|---|77| Base body font size | ≥ 16px |78| Line length | 45–75 characters (including spaces) |79| Text alignment | Follows reading direction (LTR → left-align; RTL → right-align) |80| Headings visually distinct | Larger size, bold weight, or color difference from body text |81| One `<h1>` per page | Page title only |82| Heading hierarchy | No skipped levels (h1 → h2 → h3, never h1 → h3) |83| Semantic heading tags | Use `<h1>`–`<h6>`, not styled `<div>` or `<p>` |84| Language | Plain language, secondary-education reading level |85| Idioms & figures of speech | Avoid — confuse screen readers and non-native speakers |86| Typeface | Clear letterform distinctions (0 vs O, 1 vs l vs I); large x-height |8788---8990### 3. Forms9192| Check | Requirement |93|---|---|94| Keyboard access | Every field, dropdown, checkbox, radio, button navigable via Tab / Shift+Tab / Enter / arrows |95| Focus indicators | Visible on every focused element — never remove browser default without replacing |96| Layout | Single-column preferred; multi-column increases cognitive load and screen-reader confusion |97| Input boundaries | Visible borders or backgrounds — never borderless inputs |98| Labels | Outside the field, not placeholder-only; min 16px; 4.5:1 contrast |99| Placeholder text | Supplemental only — disappears on input, so never the sole label |100| Autocomplete | Implement for name, email, phone, address, payment (HTML `autocomplete` attribute) |101| Error states | Multiple cues: icon + bold border + field-specific message. Never color alone |102| Error placement | Adjacent to the offending field + `aria-describedby` linking field to error |103| Error summary | At top of form on submit failure, with anchor links to each problem field |104| Authentication | No text-based CAPTCHA — use magic links, OTP, passkeys, or biometrics. Support paste in password fields |105| Mobile one-handed use | Center CTAs in lower-middle zone; avoid right-edge-only button placement |106107---108109### 4. Links & Navigation110111| Check | Requirement |112|---|---|113| Link labels | Descriptive, specific — "Download pricing guide" not "Click here" or "Read more" |114| New-window links | Warn users in link text or aria-label: "opens in new tab" |115| File links | State type + size: "Annual Report (PDF, 2.5 MB)" |116| Raw URLs as link text | ❌ Never — screen readers read character by character |117| Link recognizability | Underline + color (not color alone) |118| Focus state | Visible, distinctive focus ring on every link and interactive element |119| `href` attribute | Required on all `<a>` tags — `<div>` with click handler is not a link |120| Voice/tone | Link text should match the product's voice, but always prioritize clarity |121| Help links | Consistently placed (footer, header utility nav, or persistent help icon) |122123---124125### 5. Images & Multimedia126127| Check | Requirement |128|---|---|129| Informational images | `alt` attribute with meaningful description |130| Decorative images | `alt=""` (null) — tells screen readers to skip |131| Images containing text | Alt text = the exact text in the image |132| Autoplay | ❌ Disabled by default — user must initiate playback |133| Media controls | Play/pause/stop/rewind/volume/mute/captions — keyboard accessible, sufficient size and contrast |134| Video captions | Required for all pre-recorded video with audio |135| Audio transcripts | Required for all audio-only content |136| Flashing/strobing content | ❌ No content flashing > 3 Hz or red flashing at any rate |137| Animations (GIF, SVG, CSS) | No more than 5 light-dark stripe pairs; provide a way to pause/stop |138| Icons | Pair with text labels; informational icons need `aria-label` or title |139| Swipe gestures | Support both directions or provide an alternate tap target |140141---142143### 6. Tables & Lists144145| Check | Requirement |146|---|---|147| Data tables | Use `<table>` element — never use tables for layout |148| Table caption | `<caption>` immediately after `<table>` opening tag |149| Header cells | `<th>` with `scope="col"` or `scope="row"` — never empty |150| Complex tables | Avoid merged cells and multi-level headers; split into simpler tables if needed |151| Cell widths | Use `%` not `px` — allows browser reflow; never set cell height manually |152| Lists | Use `<ul>`, `<ol>`, or `<dl>` appropriately — not styled `<div>` rows |153| Unordered lists | For items where order doesn't matter |154| Ordered lists | For sequential steps, rankings, instructions |155| Description lists | `<dl>` / `<dt>` / `<dd>` for glossaries, FAQs, key-value metadata |156157---158159## Severity rating160161Rate each finding by **how completely it blocks access** and **which WCAG level it fails**:162163| Severity | Meaning |164|---|---|165| **Critical** | Blocks access entirely for some users. Usually a **Level A** failure — no keyboard access, no alt text on informational images, missing captions, a keyboard trap. Fix before ship. |166| **Major** | Significant friction; users can sometimes work around it but shouldn't have to. Usually a **Level AA** failure — contrast below 4.5:1, placeholder-as-label, color-only error states, missing focus indicators. |167| **Minor** | Noticeable but low-impact, or a best-practice / **AAA** improvement — slightly short line length, stark pure-black text, a non-ideal but functional label. |168169When in doubt, rate by the user impact (does it *block* a task or merely add friction?), not by how easy the fix is.170171---172173## Audit output format174175```176## Accessibility Audit — [Component / Screen Name]177Context: [platform · WCAG target (default AA) · design or code]178179### Critical (blocks access entirely)180- [Issue]: [what's wrong] → [fix] — WCAG [X.X.X]181182### Major (significant friction)183- [Issue]: [what's wrong] → [fix] — WCAG [X.X.X]184185### Minor (best practice / AAA)186- [Issue]: [what's wrong] → [fix] — WCAG [X.X.X]187188### Passed ✓189- [what's already working]190```191192Always end with a one-line summary stating the overall **WCAG AA compliance status** and the top fixes that would get it there.193194---195196## How to run a good audit1971981. **Establish context.** Platform (web/mobile/native), target level (AA by default — only go AAA if asked), and whether you're auditing a design or live code (some checks, like keyboard order and `aria-*`, only apply to code).1992. **Sweep all six categories.** The value of this skill over a default review is completeness — don't stop at contrast and alt text.2003. **Rate by barrier, not by effort.** A one-line `alt` fix can still be Critical.2014. **Be specific in fixes.** Give the exact change (markup, attribute, ratio, or design adjustment), not "make it accessible."2025. **Note tooling limits.** Automated scanners catch only ~30–40% of issues — manual review of focus order, alt-text quality, and reading order still matters.203204---205206## Recommended tools207208For automated scanning (catches ~30–40% of issues):209210- **WAVE** (browser extension) — overlays visual indicators, references violated WCAG criteria211- **axe DevTools** (Chrome extension) — accurate, dev-friendly; powered by axe-core212- **Google Lighthouse** (Chrome DevTools → Lighthouse tab) — accessibility + SEO + performance in one pass213214For contrast checking in design:215216- **Able** (Figma plugin) — contrast checker + color-blindness simulator217- **Stark** (Figma / Sketch / Adobe XD) — contrast, vision simulator, focus order, alt-text annotations218- **WCAG Color Contrast Checker** (Chrome extension) — real-time ratio checking in browser219220For screen-reader testing:221222- **VoiceOver** (macOS/iOS, built-in) — navigate with `VO + arrow keys`223- **NV Access / NVDA** (Windows, free) — most widely used Windows screen reader224225For seizure risk:226227- **PEAT** (downloadable) — analyzes video/animation for photosensitive epilepsy triggers228- **Harding Test** — online paid service for broadcast/video content229230---231232## Common do/don't patterns233234| ❌ Don't | ✅ Do |235|---|---|236| Use red text alone for errors | Red border + warning icon + descriptive message |237| `<a>Click here</a>` | `<a>Download the onboarding guide (PDF, 1.2 MB)</a>` |238| `<img src="chart.png">` (no alt) | `<img src="chart.png" alt="Bar chart showing Q3 revenue by region">` |239| Decorative image with alt text | `<img src="bg-swoosh.svg" alt="">` |240| Pure black `#000` on pure white `#FFF` | Dark grey `#333` on off-white `#F8F8F8` |241| Placeholder as the only label | Persistent label above the field + optional placeholder |242| Jump from `<h1>` to `<h3>` | Always use `<h1>` → `<h2>` → `<h3>` in order |243| Table for page layout | CSS Grid or Flexbox for layout; `<table>` for data only |244| Autoplay video | Controls visible at top; user initiates playback |245| Color-only chart legend | Add patterns, shapes, or data labels alongside color |246| Report only the obvious issues | Sweep all six categories; rate by barrier; cite the criterion |247248---249250## Source lessons (Uxcel)251252- [Intro to Accessibility](https://uxcel.com/lessons/intro-to-accessibility-816)253- [Accessibility Tools](https://uxcel.com/lessons/accessibility-tools-156)254- [Color Accessibility](https://uxcel.com/lessons/accessible-colors-417)255- [Text Accessibility](https://uxcel.com/lessons/accessible-text-698)256- [Forms Accessibility](https://uxcel.com/lessons/accessible-forms-582)257- [Links Accessibility](https://uxcel.com/lessons/accessible-links-903)258- [Multimedia Accessibility](https://uxcel.com/lessons/accessible-multimedia-295)259- [Tables & Lists Accessibility](https://uxcel.com/lessons/accessible-tables-712)