Accessibility Audit Helper — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Accessibility Audit Helper (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill directs the agent to review HTML, JSX, or React component code for WCAG 2.1 accessibility violations. It checks for missing alt text, improper heading hierarchy, ARIA misuse, keyboard trap risks, color contrast hints, missing focus indicators, and more. Every finding is categorized by severity with a concrete before/after code fix included.
Use this before shipping any UI feature, during code review, or as a regular accessibility sweep of your component library.
Copy this file to .agents/skills/accessibility-audit-helper/SKILL.md in your project root.
Then share the component or page code and ask:
Paste the component code directly or provide a file path for the agent to read.
Add the "Prompt / Instructions" section to your .cursorrules file. Open the component you want audited and ask Cursor to run an accessibility audit.
Paste the component or page HTML/JSX into the chat along with the instructions below.
When asked to audit UI code for accessibility, follow these steps:
Images and Media
<img> elements must have an alt attribute; decorative images use alt=""aria-label or aria-labelledby<title> or aria-label; decorative SVGs need aria-hidden="true"Heading Hierarchy
<h1>Interactive Elements
aria-labelrole, tabIndex={0}, and keyboard event handlers (onKeyDown for Enter/Space)<button> elements must not be nested inside <a> tags, and vice versaForms
<label> (via htmlFor/id, aria-label, or aria-labelledby)aria-required="true" or requiredaria-describedby<fieldset> and <legend>Keyboard and Focus
tabIndex values (1, 2, 3...) — these break natural tab orderoutline: none without a replacement focus style)ARIA
role="button" to an already-interactive <button>aria-hidden="true" must not be applied to elements that contain focusable childrenaria-live) should be used for dynamically updated content (status messages, alerts)aria-label on non-interactive elements unless there's a semantic reasonColor and Contrast (static analysis)
Document Structure
<main> landmark, a <header>, and a <nav> (when applicable)aria-label when multiple <nav> elements exist on a page## Accessibility Audit Results
### Summary
[X] Critical violations · [Y] Serious violations · [Z] Moderate violations
---
### Critical Violations
#### 1. [Violation title] — WCAG 2.1 SC [X.X.X]
**Problem:** [Plain English explanation]
**Location:** [Element / line description]
**Before:**[problematic code]
**Fix:**[corrected code]
---
[repeat for each finding, grouped by severity]
### Passed Checks
- [List checks that passed cleanly]Input to Agent:
"Use the Accessibility Audit Helper skill on this component:
>
``tsx export function SearchBar({ onSearch }) { return ( <div> <input type="text" placeholder="Search..." onChange={e => onSearch(e.target.value)} /> <div onClick={onSearch} style={{ cursor: 'pointer' }}> <svg width="16" height="16"><path d="M..."/></svg> </div> </div> ); } ``"Output from Agent:
## Accessibility Audit Results
>
### Summary 2 Critical violations · 1 Serious violation · 0 Moderate violations
>
---
>
### Critical Violations
>
#### 1. Input has no label — WCAG 2.1 SC 1.3.1 Problem: The text input has no associated label. Screen readers will only announce "edit text" with no context about its purpose. Location: <input type="text" placeholder="Search...">>
Before: ``tsx <input type="text" placeholder="Search..." onChange={...} /> ``>
Fix: ``tsx <label htmlFor="search-input" className="sr-only">Search</label> <input id="search-input" type="text" placeholder="Search..." onChange={...} /> ``>
#### 2. SVG icon has no accessible name — WCAG 2.1 SC 1.1.1 Problem: The SVG is inside a clickable element but has no title or aria-label. Screen readers cannot determine its purpose.
>
Before: ``tsx <svg width="16" height="16"><path d="M..."/></svg> ``>
Fix: ``tsx <svg width="16" height="16" aria-hidden="true" focusable="false"><path d="M..."/></svg> `` (The parent button carries the accessible name; hide the SVG from the a11y tree.)>
---
>
### Serious Violations
>
#### 3. Clickable div is not keyboard accessible — WCAG 2.1 SC 2.1.1 Problem: A<div>with anonClickhandler is not reachable or activatable via keyboard.
>
Before: ``tsx <div onClick={onSearch} style={{ cursor: 'pointer' }}>...</div> ``>
Fix: ``tsx <button type="button" onClick={onSearch} aria-label="Search">...</button> ``>
---
>
### Passed Checks - No positive tabIndex values - No aria-hidden on focusable children - No heading hierarchy issues
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.