Accessibility Auditor
Audits frontend source code and HTML for WCAG 2.1 (AA) compliance issues — identifying missing alt text, insufficient color contrast, improper ARIA usage, keyboard navigation gaps, focus management problems, and semantic HTML violations — with prioritized, actionable remediations.
When to Use
- User asks to "check accessibility", "audit for a11y issues", or "ensure WCAG compliance"
- A new UI component needs to be verified before shipping
- Screen reader users are reporting issues
- An accessibility audit has been requested (legal compliance, VPAT)
- User asks about ARIA roles, focus management, or keyboard navigation
- Color contrast or font size concerns are raised
Process
Identify the source type:
- HTML source or rendered output
- React/JSX components
- Vue/Svelte/Angular templates
- CSS (for color contrast and focus styles)
Audit against WCAG 2.1 success criteria organized by the four POUR principles:
Perceivable (users can perceive all content)
- 1.1.1 Non-text Content: Every
<img>, <svg>, icon button, and canvas needs alt text or aria-label; decorative images need alt=""
- 1.3.1 Info and Relationships: Use semantic HTML (
<nav>, <main>, <header>, <aside>, <section>, headings hierarchy h1→h2→h3)
- 1.3.3 Sensory Characteristics: Don't rely on color alone to convey information (add icons, patterns, or text labels)
- 1.4.1 Use of Color: Ensure information is not conveyed by color alone
- 1.4.3 Contrast (Minimum): Text contrast ratio ≥ 4.5:1 (AA), large text ≥ 3:1
- 1.4.4 Resize Text: Content must be usable at 200% zoom without loss of functionality
- 1.4.10 Reflow: Content must not require horizontal scrolling at 320px width
Operable (users can operate the interface)
- 2.1.1 Keyboard: All functionality available via keyboard; no keyboard traps
- 2.1.2 No Keyboard Trap: Focus must be able to leave any component
- 2.4.1 Bypass Blocks: Provide skip navigation link to main content
- 2.4.3 Focus Order: Focus moves in a logical, meaningful order
- 2.4.4 Link Purpose: Link text describes the destination (not "click here")
- 2.4.7 Focus Visible: Keyboard focus indicator must be clearly visible
- 2.5.3 Label in Name: Visible label text must be included in accessible name
Understandable (users can understand the content)
- 3.1.1 Language of Page:
<html lang="en"> (or appropriate language code) must be set
- 3.2.1 On Focus: No unexpected context changes when an element receives focus
- 3.3.1 Error Identification: Form errors identified in text, not just color
- 3.3.2 Labels or Instructions: Form inputs must have associated
<label> elements
Robust (content can be interpreted by assistive technologies)
- 4.1.1 Parsing: Valid HTML — no duplicate IDs, properly nested elements
- 4.1.2 Name, Role, Value: Custom widgets must have correct ARIA roles, states, and properties
- 4.1.3 Status Messages: Live regions (
aria-live, role="status") for dynamic content
Audit ARIA usage:
- Verify ARIA roles are used correctly (don't add
role="button" to a native <button>)
aria-label / aria-labelledby present for elements without visible text
aria-expanded, aria-selected, aria-checked state managed correctly for interactive widgets
aria-hidden="true" not applied to focusable elements
Check interactive component patterns:
- Modals/dialogs: focus trapped inside when open, returns to trigger on close,
role="dialog", aria-modal="true"
- Dropdowns/menus: keyboard navigation (arrows),
role="menu", role="menuitem"
- Tabs:
role="tablist", role="tab", aria-selected, arrow key navigation
- Carousels/sliders: pause mechanism, keyboard controls
Categorize findings by WCAG level (A / AA / AAA) and severity.
Output Format
## Accessibility Audit Report
**Standard:** WCAG 2.1 Level AA
**Component:** `ProductCard.tsx`
**Findings:** 🔴 3 critical · 🟡 2 warnings · 🟢 2 enhancements
---
### 🔴 Critical — Missing alt text (WCAG 1.1.1, Level A)
**Element:** `<img src={product.imageUrl} />`
All product images lack alt text. Screen readers will announce the filename.
**Fix:**
```jsx
<img src={product.imageUrl} alt={product.name} />
// For decorative images:
<img src={decorativeBackground} alt="" role="presentation" />
🔴 Critical — Button has no accessible name (WCAG 4.1.2, Level A)
Element: <button /></button>
Icon-only buttons need an accessible label.
Fix:
<button aria-label={`Add ${product.name} to cart`}>
<CartIcon aria-hidden="true" />
</button>
🟡 Warning — Insufficient color contrast (WCAG 1.4.3, Level AA)
Element: .product-price — color: #aaa on white background
Contrast ratio: 2.32:1 (required: 4.5:1)
Fix: Change to color: #767676 (minimum 4.54:1) or darker.
## Examples
### Example Input
```html
<div style="color: #ccc">
View Product
</div>
<img src="shoe.jpg">
<input type="text" placeholder="Search...">
Example Output
🔴 Critical — Interactive element is not keyboard accessible (WCAG 2.1.1)
A <div> with onclick is not focusable or operable by keyboard.
Fix: Use <button> or <a href> instead.
🔴 Critical — Image missing alt text (WCAG 1.1.1)
<img src="shoe.jpg"> has no alt attribute.
Fix: <img src="shoe.jpg" alt="White running shoe">
🟡 Warning — Input missing associated label (WCAG 1.3.1)
Placeholder text is not a substitute for a <label>.
Fix: <label for="search">Search</label> <input id="search" type="text">
🟡 Warning — Insufficient contrast on text (WCAG 1.4.3)
#ccc on white = 1.6:1 ratio (required: 4.5:1)
Boundaries
- Do NOT audit color contrast without the actual color values —
color: var(--text-muted) requires resolving the CSS variable.
- Do NOT audit rendered behavior (focus trapping, live regions) from static source alone — note when dynamic behavior must be tested with a screen reader (NVDA, JAWS, VoiceOver) or automated tool (axe-core, Lighthouse).
- Do NOT recommend
aria-* attributes as a substitute for semantic HTML — prefer native elements.
- Do NOT recommend removing ARIA attributes that are correctly implemented — only flag incorrect usage.
- WCAG AAA criteria are optional for most compliance requirements — focus on A and AA unless AAA is specified.
- If the codebase uses a design system, check if the design system components are already accessible before flagging usage-level issues.
1---2name: accessibility-auditor3description: Scans frontend code and rendered HTML for WCAG 2.1 compliance issues — missing alt text, color contrast, ARIA roles, keyboard navigation. Invoke when asked to check accessibility, audit WCAG compliance, find a11y issues, improve screen reader support, or ensure keyboard navigation works.4---56# Accessibility Auditor78Audits frontend source code and HTML for WCAG 2.1 (AA) compliance issues — identifying missing alt text, insufficient color contrast, improper ARIA usage, keyboard navigation gaps, focus management problems, and semantic HTML violations — with prioritized, actionable remediations.910## When to Use1112- User asks to "check accessibility", "audit for a11y issues", or "ensure WCAG compliance"13- A new UI component needs to be verified before shipping14- Screen reader users are reporting issues15- An accessibility audit has been requested (legal compliance, VPAT)16- User asks about ARIA roles, focus management, or keyboard navigation17- Color contrast or font size concerns are raised1819## Process20211. **Identify the source type**:22 - HTML source or rendered output23 - React/JSX components24 - Vue/Svelte/Angular templates25 - CSS (for color contrast and focus styles)26272. **Audit against WCAG 2.1 success criteria** organized by the four POUR principles:2829 **Perceivable (users can perceive all content)**30 - 1.1.1 Non-text Content: Every `<img>`, `<svg>`, icon button, and canvas needs `alt` text or `aria-label`; decorative images need `alt=""`31 - 1.3.1 Info and Relationships: Use semantic HTML (`<nav>`, `<main>`, `<header>`, `<aside>`, `<section>`, headings hierarchy `h1→h2→h3`)32 - 1.3.3 Sensory Characteristics: Don't rely on color alone to convey information (add icons, patterns, or text labels)33 - 1.4.1 Use of Color: Ensure information is not conveyed by color alone34 - 1.4.3 Contrast (Minimum): Text contrast ratio ≥ 4.5:1 (AA), large text ≥ 3:135 - 1.4.4 Resize Text: Content must be usable at 200% zoom without loss of functionality36 - 1.4.10 Reflow: Content must not require horizontal scrolling at 320px width3738 **Operable (users can operate the interface)**39 - 2.1.1 Keyboard: All functionality available via keyboard; no keyboard traps40 - 2.1.2 No Keyboard Trap: Focus must be able to leave any component41 - 2.4.1 Bypass Blocks: Provide skip navigation link to main content42 - 2.4.3 Focus Order: Focus moves in a logical, meaningful order43 - 2.4.4 Link Purpose: Link text describes the destination (not "click here")44 - 2.4.7 Focus Visible: Keyboard focus indicator must be clearly visible45 - 2.5.3 Label in Name: Visible label text must be included in accessible name4647 **Understandable (users can understand the content)**48 - 3.1.1 Language of Page: `<html lang="en">` (or appropriate language code) must be set49 - 3.2.1 On Focus: No unexpected context changes when an element receives focus50 - 3.3.1 Error Identification: Form errors identified in text, not just color51 - 3.3.2 Labels or Instructions: Form inputs must have associated `<label>` elements5253 **Robust (content can be interpreted by assistive technologies)**54 - 4.1.1 Parsing: Valid HTML — no duplicate IDs, properly nested elements55 - 4.1.2 Name, Role, Value: Custom widgets must have correct ARIA roles, states, and properties56 - 4.1.3 Status Messages: Live regions (`aria-live`, `role="status"`) for dynamic content57583. **Audit ARIA usage**:59 - Verify ARIA roles are used correctly (don't add `role="button"` to a native `<button>`)60 - `aria-label` / `aria-labelledby` present for elements without visible text61 - `aria-expanded`, `aria-selected`, `aria-checked` state managed correctly for interactive widgets62 - `aria-hidden="true"` not applied to focusable elements63644. **Check interactive component patterns**:65 - Modals/dialogs: focus trapped inside when open, returns to trigger on close, `role="dialog"`, `aria-modal="true"`66 - Dropdowns/menus: keyboard navigation (arrows), `role="menu"`, `role="menuitem"`67 - Tabs: `role="tablist"`, `role="tab"`, `aria-selected`, arrow key navigation68 - Carousels/sliders: pause mechanism, keyboard controls69705. **Categorize findings** by WCAG level (A / AA / AAA) and severity.7172## Output Format7374```75## Accessibility Audit Report7677**Standard:** WCAG 2.1 Level AA78**Component:** `ProductCard.tsx`79**Findings:** 🔴 3 critical · 🟡 2 warnings · 🟢 2 enhancements8081---8283### 🔴 Critical — Missing alt text (WCAG 1.1.1, Level A)84**Element:** `<img src={product.imageUrl} />`8586All product images lack alt text. Screen readers will announce the filename.8788**Fix:**89```jsx90<img src={product.imageUrl} alt={product.name} />91// For decorative images:92<img src={decorativeBackground} alt="" role="presentation" />93```9495---9697### 🔴 Critical — Button has no accessible name (WCAG 4.1.2, Level A)98**Element:** `<button onClick={onAddToCart}><CartIcon /></button>`99100Icon-only buttons need an accessible label.101102**Fix:**103```jsx104<button onClick={onAddToCart} aria-label={`Add ${product.name} to cart`}>105 <CartIcon aria-hidden="true" />106</button>107```108109---110111### 🟡 Warning — Insufficient color contrast (WCAG 1.4.3, Level AA)112**Element:** `.product-price` — `color: #aaa` on white background113**Contrast ratio:** 2.32:1 (required: 4.5:1)114115**Fix:** Change to `color: #767676` (minimum 4.54:1) or darker.116```117118## Examples119120### Example Input121```html122<div onclick="navigate('/product/1')" style="color: #ccc">123 View Product124</div>125<img src="shoe.jpg">126<input type="text" placeholder="Search...">127```128129### Example Output130```131🔴 Critical — Interactive element is not keyboard accessible (WCAG 2.1.1)132A <div> with onclick is not focusable or operable by keyboard.133Fix: Use <button> or <a href> instead.134135🔴 Critical — Image missing alt text (WCAG 1.1.1)136<img src="shoe.jpg"> has no alt attribute.137Fix: <img src="shoe.jpg" alt="White running shoe">138139🟡 Warning — Input missing associated label (WCAG 1.3.1)140Placeholder text is not a substitute for a <label>.141Fix: <label for="search">Search</label> <input id="search" type="text">142143🟡 Warning — Insufficient contrast on text (WCAG 1.4.3)144#ccc on white = 1.6:1 ratio (required: 4.5:1)145```146147## Boundaries148149- Do NOT audit color contrast without the actual color values — `color: var(--text-muted)` requires resolving the CSS variable.150- Do NOT audit rendered behavior (focus trapping, live regions) from static source alone — note when dynamic behavior must be tested with a screen reader (NVDA, JAWS, VoiceOver) or automated tool (axe-core, Lighthouse).151- Do NOT recommend `aria-*` attributes as a substitute for semantic HTML — prefer native elements.152- Do NOT recommend removing ARIA attributes that are correctly implemented — only flag incorrect usage.153- WCAG AAA criteria are optional for most compliance requirements — focus on A and AA unless AAA is specified.154- If the codebase uses a design system, check if the design system components are already accessible before flagging usage-level issues.