Accessibility audit skill for scanning, fixing, and verifying WCAG 2.2 Level A and AA compliance across React, Next.js, Vue, Angular, Svelte, and plain HTML codebases. Use when auditing accessibility, fixing a11y violations, checking color contrast, generating compliance reports, or integrating accessibility checks into CI/CD pipelines.
Accessibility audit skill for scanning, fixing, and verifying WCAG 2.2 Level A and AA compliance across React, Next.js, Vue, Angular, Svelte, and plain HTML codebases. Use when auditing accessibility, fixing a11y violations, checking color contrast, generating compliance reports, or integrating accessibility checks into CI/CD pipelines.
license
MIT
metadata
{"updated":"2026-03-18T00:00:00.000Z"}
Accessibility Audit
Name: a11y-audit
Tier: STANDARD
Category: Engineering - Frontend Quality
Dependencies: Python 3.8+ (Standard Library Only)
Author: Alireza Rezvani
Version: 2.1.2
Last Updated: 2026-03-18
License: MIT
Name
a11y-audit -- WCAG 2.2 Accessibility Audit and Remediation Skill
Description
The a11y-audit skill provides a complete accessibility audit pipeline for modern web applications. It implements a three-phase workflow -- Scan, Fix, Verify -- that identifies WCAG 2.2 Level A and AA violations, generates exact fix code per framework, and produces stakeholder-ready compliance reports.
This skill goes beyond detection. For every violation it finds, it provides the precise before/after code fix tailored to your framework (React, Next.js, Vue, Angular, Svelte, or plain HTML). It understands that a missing alt attribute on an <img> in React JSX requires a different fix pattern than the same issue in a Vue SFC or an Angular template.
What this skill does:
Scans your codebase for every WCAG 2.2 Level A and AA violation, categorized by severity (Critical, Major, Minor)
Fixes each violation with framework-specific before/after code patterns
Verifies that fixes resolve the original violations and introduces no regressions
Reports findings in a structured format suitable for developers, PMs, and compliance stakeholders
Integrates into CI/CD pipelines to prevent accessibility regressions
Key differentiators:
Framework-aware fix patterns (not generic HTML advice)
Color contrast analysis with accessible alternative suggestions
WCAG 2.2 coverage including the newest success criteria (Focus Appearance, Dragging Movements, Target Size)
CI/CD pipeline integration with GitHub Actions, GitLab CI, and Azure DevOps
Slash command support via /a11y-audit
Features
Core Capabilities
Feature
Description
Full WCAG 2.2 Scan
Checks all Level A and AA success criteria across your codebase
Framework Detection
Auto-detects React, Next.js, Vue, Angular, Svelte, or plain HTML
Severity Classification
Categorizes each violation as Critical, Major, or Minor
Fix Code Generation
Produces before/after code diffs for every issue
Color Contrast Checker
Validates foreground/background pairs against AA and AAA ratios
Accessible Alternatives
Suggests replacement colors that meet contrast requirements
Compliance Reporting
Generates stakeholder reports with pass/fail summaries
// BEFORE
<img src={hero} />
// AFTER - Informational image<imgsrc={hero}alt="Team collaborating around a whiteboard" />// AFTER - Decorative image<imgsrc={divider}alt=""role="presentation" />
Non-Interactive Element with Click Handler (2.1.1)
// BEFORE
<div onClick={handleClick}>Click me</div>
// AFTER - If it navigates<Linkhref="/destination">Click me</Link>// AFTER - If it performs an action<buttontype="button"onClick={handleClick}>Click me</button>
<!-- +page.svelte -->
<svelte:head>
<title>Dashboard | My App</title>
</svelte:head>
Plain HTML Fix Patterns
Skip Navigation Link (2.4.1)
<!-- BEFORE --><body><nav><!-- long navigation --></nav><main><!-- content --></main></body><!-- AFTER --><body><ahref="#main-content"class="skip-link">Skip to main content</a><navaria-label="Main navigation"><!-- long navigation --></nav><mainid="main-content"tabindex="-1"><!-- content --></main></body>
<!-- BEFORE --><table><tr><td>Name</td><td>Email</td><td>Role</td></tr><tr><td>Alice</td><td>alice@co.com</td><td>Admin</td></tr></table><!-- AFTER --><tablearia-label="Team members"><captionclass="sr-only">List of team members and their roles</caption><thead><tr><thscope="col">Name</th><thscope="col">Email</th><thscope="col">Role</th></tr></thead><tbody><tr><thscope="row">Alice</th><td>alice@co.com</td><td>Admin</td></tr></tbody></table>
Color Contrast Checker
The contrast_checker.py script validates color pairs against WCAG 2.2 contrast requirements.
Usage
# Check a single color pair
python scripts/contrast_checker.py --fg"#777777" --bg"#ffffff"# Output:# Foreground: #777777 | Background: #ffffff# Contrast Ratio: 4.48:1# AA Normal Text (4.5:1): FAIL# AA Large Text (3.0:1): PASS# AAA Normal Text (7.0:1): FAIL# Suggested alternative: #767676 (4.54:1 - passes AA)# Scan a CSS file for all color pairs
python scripts/contrast_checker.py --file src/styles/globals.css
# Scan Tailwind classes in components
python scripts/contrast_checker.py --tailwind src/components/
Common Contrast Fixes
Original Color
Contrast on White
Fix
New Contrast
#aaaaaa
2.32:1
#767676
4.54:1 (AA)
#999999
2.85:1
#767676
4.54:1 (AA)
#888888
3.54:1
#767676
4.54:1 (AA)
#777777
4.48:1
#757575
4.60:1 (AA)
#66bb6a
3.06:1
#2e7d32
5.87:1 (AA)
#42a5f5
2.81:1
#1565c0
6.08:1 (AA)
#ef5350
3.13:1
#c62828
5.57:1 (AA)
Tailwind CSS Accessible Palette Mapping
Inaccessible Class
Contrast on White
Accessible Alternative
Contrast
text-gray-400
2.68:1
text-gray-600
5.74:1
text-blue-400
2.81:1
text-blue-700
5.96:1
text-green-400
2.12:1
text-green-700
5.18:1
text-red-400
3.04:1
text-red-700
6.05:1
text-yellow-500
1.47:1
text-yellow-800
7.34:1
CI/CD Integration
GitHub Actions
# .github/workflows/a11y-audit.ymlname:AccessibilityAuditon:pull_request:paths:-'src/**/*.tsx'-'src/**/*.vue'-'src/**/*.html'-'src/**/*.svelte'jobs:a11y-audit:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-name:SetupPythonuses:actions/setup-python@v5with:python-version:'3.11'-name:RunA11yScannerrun:|
python scripts/a11y_scanner.py ./src --json > a11y-results.json
-name:CheckforCriticalIssuesrun:|
python -c "
import json, sys
with open('a11y-results.json') as f:
data = json.load(f)
critical = [v for v in data.get('violations', []) if v['severity'] == 'critical']
if critical:
print(f'FAILED: {len(critical)} critical a11y violations found')
for v in critical:
print(f\" [{v['wcag']}] {v['file']}:{v['line']} - {v['message']}\")
sys.exit(1)
print('PASSED: No critical a11y violations')
"
-name:UploadAuditReportif:always()uses:actions/upload-artifact@v4with:name:a11y-audit-reportpath:a11y-results.json-name:CommentonPRif:failure()uses:marocchino/sticky-pull-request-comment@v2with:header:a11y-auditmessage:|
## Accessibility Audit Failed
Critical WCAG 2.2 violations were found. See the uploaded artifact for details.
Run `python scripts/a11y_scanner.py ./src` locally to view and fix issues.
GitLab CI
# .gitlab-ci.ymla11y-audit:stage:testimage:python:3.11-slimscript:-pythonscripts/a11y_scanner.py./src--json>a11y-results.json-python-c"
import json, sys;
data = json.load(open('a11y-results.json'));
critical = [v for v in data.get('violations', []) if v['severity'] == 'critical'];
sys.exit(1) if critical else print('A11y audit passed')
"artifacts:paths:-a11y-results.jsonwhen:alwaysrules:-changes:-"src/**/*.{tsx,vue,html,svelte}"
# Accessibility Audit Report**Project:** Acme Dashboard
**Date:** 2026-03-18
**Standard:** WCAG 2.2 Level AA
**Tool:** a11y-audit v2.1.2
## Executive Summary- Files Scanned: 127
- Total Violations: 14
- Critical: 3 | Major: 7 | Minor: 4
- Estimated Remediation: 8-12 hours
- Compliance Score: 72% (Target: 100%)
## Violations by Category
| Category | Count | Severity Breakdown |
|----------|-------|--------------------|
| Missing Alt Text | 3 | 2 Critical, 1 Minor |
| Keyboard Access | 4 | 2 Critical, 2 Major |
| Color Contrast | 3 | 3 Major |
| Form Labels | 2 | 2 Major |
| ARIA Usage | 2 | 2 Minor |
## Detailed Findings
[Per-violation details with file, line, WCAG criterion, and fix]
## Remediation Priority1. Fix all Critical issues (blocks release)
2. Fix Major issues in current sprint
3. Schedule Minor issues for next sprint
## Recommendations- Add a11y linting to CI pipeline (eslint-plugin-jsx-a11y)
- Include keyboard testing in QA checklist
- Schedule quarterly manual audit with assistive technology
Tools Reference
a11y_scanner.py
Scans source files for WCAG 2.2 violations.
Usage: python scripts/a11y_scanner.py <path> [options]
Arguments:
path File or directory to scan
Options:
--json Output results as JSON
--format {table,csv} Output format (default: table)
--severity {critical,major,minor}
Filter by minimum severity
--framework {react,vue,angular,svelte,html,auto}
Force framework (default: auto-detect)
--baseline FILE Compare against previous scan results
--report Generate stakeholder report
--output FILE Write results to file
--quiet Suppress output, exit code only
--ci CI mode: non-zero exit on critical issues
contrast_checker.py
Validates color contrast ratios against WCAG 2.2 requirements.
Usage: python scripts/contrast_checker.py [options]
Options:
--fg COLOR Foreground color (hex)
--bg COLOR Background color (hex)
--file FILE Scan CSS file for color pairs
--tailwind DIR Scan directory for Tailwind color classes
--json Output results as JSON
--suggest Suggest accessible alternatives for failures
--level {aa,aaa} Target conformance level (default: aa)
Testing Checklist
Use this checklist after applying fixes to verify accessibility manually:
Keyboard Navigation
All interactive elements reachable via Tab key
Tab order follows visual/logical reading order
Focus indicator visible on every focusable element (2px+ outline)
Modals trap focus and return focus on close
Escape key closes modals, dropdowns, and popups
Arrow keys navigate within composite widgets (tabs, menus, listboxes)
No keyboard traps (user can always Tab away)
Screen Reader
All images have appropriate alt text (or alt="" for decorative)
Any functionality that uses dragging must have a single-pointer alternative (click, tap).
Pattern:
// Sortable list: support both drag and button-based reorder
<li draggable onDragStart={handleDrag}>
{item.name}
<button onClick={() =>moveUp(index)} aria-label={`Move ${item.name} up`}>
MoveUp
</button>
<buttononClick={() => moveDown(index)} aria-label={`Move ${item.name} down`}>
Move Down
</button>
</li>
2.5.8 Target Size (Level AA)
Interactive targets must be at least 24x24 CSS pixels, with exceptions for inline text links and elements where the spacing provides equivalent clearance.