Web Accessibility Audit logo

Web Accessibility Audit

Organization
warpdotdev
web-accessibility-audit

Audit web applications for WCAG accessibility compliance. Use when asked to run accessibility checks, identify common violations, and provide remediation guidance.

Overview

Publisherwarpdotdev
Repositoryoz-skills
Skill nameweb-accessibility-audit
Stars
824
Forks
68
Bundled files
5
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 5 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by warpdotdev on GitHub. Read the source before you install it.

Installation

Install the Web Accessibility Audit AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/warpdotdev/oz-skills/tree/main/.agents/skills/web-accessibility-audit
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/warpdotdev/oz-skills.git /tmp/oz-skills
mkdir -p .claude/skills
cp -r /tmp/oz-skills/.agents/skills/web-accessibility-audit .claude/skills/web-accessibility-audit
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Web Accessibility Audit in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Web Accessibility Audit on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Web Accessibility Audit is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Accessibility Auditor

Audit web applications for WCAG 2.0/2.1/2.2 compliance by identifying common violations and providing actionable remediation steps.

When to Use

  • User requests accessibility audit, a11y check, or WCAG compliance review
  • User mentions accessibility issues, screen readers, or keyboard navigation problems
  • User asks to check or improve accessibility for people with disabilities

WCAG Principles: POUR

PrincipleDescription
PerceivableContent can be perceived through different senses
OperableInterface can be operated by all users
UnderstandableContent and interface are understandable
RobustContent works with assistive technologies

Conformance Levels

LevelRequirementTarget
AMinimum accessibilityMust pass
AAStandard complianceShould pass (legal requirement in many jurisdictions)
AAAEnhanced accessibilityNice to have

12 Most Common WCAG Violations

Based on WebAIM Million (2021) research analyzing top 1M websites:

  1. Low Color Contrast (WCAG 1.4.3) - 86.4% of sites

    • Text < 4.5:1 contrast ratio
    • Large text < 3:1 contrast ratio
    • UI components < 3:1
  2. Missing/Inadequate Alt Text (WCAG 1.1.1) - 60.6% of sites

    • Images without alt attribute
    • Alt text with "image", "picture", "photo"
    • Empty alt on meaningful images
  3. Missing Name, Role, or Value (WCAG 4.1.2)

    • Interactive elements without accessible names
    • Custom components without proper ARIA
    • Buttons, form fields, custom widgets
  4. Keyboard Navigation Failures (WCAG 2.1.1)

    • Elements with onClick but not keyboard accessible
    • Missing focus indicators
    • Trapped keyboard focus
  5. Unlabeled Form Controls (WCAG 1.3.1, 3.3.2) - 39.6% of sites

    • Inputs without <label> or aria-label
    • Labels not programmatically associated
  6. Missing Language Attributes (WCAG 3.1.1) - 28.9% of sites

    • No lang attribute on <html>
    • Missing lang for foreign language passages
  7. Improper Heading Structure (WCAG 1.3.1, 2.4.6)

    • Skipped heading levels (h1 → h3)
    • Multiple h1s or no h1
    • Empty headings
  8. Empty Links or Poor Link Text (WCAG 2.4.4)

    • Links with "click here", "here", "read more"
    • Empty links or links with only icons
  9. Missing/Improper Focus Indicators (WCAG 2.4.7)

    • CSS removing outline without replacement
    • Insufficient focus indicator contrast
  10. Overuse/Misuse of ARIA (WCAG 4.1.2)

    • Unnecessary ARIA when native HTML works
    • Invalid ARIA attributes for roles
    • Required ARIA attributes missing
  11. Inadequate Data Table Markup (WCAG 1.3.1)

    • Tables without <th> elements
    • Missing scope or headers attributes
  12. Missing Media Captions (WCAG 1.2.1, 1.2.2)

    • Videos without captions/subtitles
    • Audio without transcripts

Audit Process

Phase 1: Automated Testing

Run ESLint (React/JSX projects):

bash
npx eslint --ext .jsx,.tsx --no-ignore --format json . > .claude/skills/a11y-auditor/eslint-results.json 2>&1 || true

Or use helper script: .claude/skills/a11y-auditor/scripts/run-eslint.sh

Run Lighthouse (production/staging):

bash
npx lighthouse https://example.com --only-categories=accessibility --output=json --output-path=./lighthouse-results.json

Check for axe-core integration:

bash
grep -r "@axe-core\|axe-core" package.json

Phase 2: Manual Code Inspection

Use grep patterns from references/grep-patterns.md to search for:

  • Missing alt text
  • Keyboard navigation issues
  • Color values for contrast checking
  • ARIA issues
  • Form labels
  • Heading structure
  • Language attributes
  • Poor link text
  • Media elements

See references/grep-patterns.md for complete pattern list.

Phase 3: Analyze & Prioritize

Group findings by severity using WCAG impact levels:

Critical (fix immediately):

  • Keyboard traps
  • No focus indicators
  • Missing form labels
  • Missing alt text on functional images
  • Insufficient color contrast on interactive elements

Serious (fix before launch):

  • Missing page language
  • Improper heading structure
  • Non-descriptive link text
  • Missing skip links
  • Auto-playing media

Moderate (fix soon):

  • Missing ARIA labels on icons
  • Inconsistent navigation
  • Missing error identification
  • Missing landmark regions

Phase 4: Manual Testing

Follow references/screen-reader-guide.md for:

  • Keyboard navigation testing
  • Screen reader testing (VoiceOver, NVDA, JAWS)
  • Zoom and reflow testing
  • High contrast mode testing
  • Reduced motion testing

WCAG Pattern Examples

Perceivable

Alt Text (1.1.1)
html
<!-- ❌ Missing alt -->
<img src="chart.png">

<!-- ✅ Descriptive alt -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q3 sales">

<!-- ✅ Decorative (empty alt) -->
<img src="decorative-border.png" alt="" role="presentation">
Color Contrast (1.4.3)
css
/* ❌ Low contrast (2.5:1) */
.low-contrast {
  color: #999;
  background: #fff;
}

/* ✅ Sufficient contrast (7:1) */
.high-contrast {
  color: #333;
  background: #fff;
}

Contrast requirements:

  • Normal text: 4.5:1 (AA), 7:1 (AAA)
  • Large text (18px+ or 14px+ bold): 3:1 (AA), 4.5:1 (AAA)
  • UI components: 3:1
Media Alternatives (1.2)
html
<video controls>
  <source src="video.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="en" label="English" default>
</video>

Operable

Keyboard Navigation (2.1.1)
javascript
// ❌ Only click
element.addEventListener('click', handleAction);

// ✅ Click + keyboard
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault();
    handleAction();
  }
});
Focus Visible (2.4.7)
css
/* ❌ Never remove focus */
*:focus { outline: none; }

/* ✅ Keyboard-only focus */
:focus-visible {
  outline: 2px solid #005fcc;
  outline-offset: 2px;
}
Skip Links (2.4.1)
html
<body>
  <a href="#main-content" class="skip-link">Skip to main content</a>
  <header><!-- navigation --></header>
  <main id="main-content" tabindex="-1">
    <!-- content -->
  </main>
</body>
css
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px 16px;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}
Reduced Motion (2.3.3)
css
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Understandable

Page Language (3.1.1)
html
<!-- ❌ No language -->
<html>

<!-- ✅ Language specified -->
<html lang="en">

<!-- ✅ Language changes -->
<p>The French word for hello is <span lang="fr">bonjour</span>.</p>
Form Labels (3.3.2)
html
<!-- ❌ No label -->
<input type="email" placeholder="Email">

<!-- ✅ Explicit label -->
<label for="email">Email address</label>
<input type="email" id="email" autocomplete="email">

<!-- ✅ With hint -->
<label for="password">Password</label>
<input type="password" id="password" aria-describedby="password-requirements">
<p id="password-requirements">
  Must be at least 8 characters with one number.
</p>
Error Handling (3.3.1)
html
<label for="email">Email</label>
<input type="email" id="email" 
       aria-invalid="true" 
       aria-describedby="email-error">
<p id="email-error" role="alert">
  Please enter a valid email address.
</p>

Robust

ARIA Usage (4.1.2)
html
<!-- ❌ Unnecessary ARIA -->
<button role="button">Submit</button>

<!-- ✅ Native HTML -->
<button>Submit</button>

<!-- ✅ ARIA when needed (custom tabs) -->
<div role="tablist" aria-label="Product information">
  <button role="tab" aria-selected="true" aria-controls="panel-1">
    Description
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-2" tabindex="-1">
    Reviews
  </button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
  <!-- content -->
</div>
Live Regions (4.1.3)
html
<!-- Polite (waits for pause) -->
<div aria-live="polite" aria-atomic="true">
  Status update
</div>

<!-- Assertive (interrupts) -->
<div role="alert" aria-live="assertive">
  Error: Form submission failed
</div>
Visually Hidden Text
css
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
html
<button>
  <svg aria-hidden="true"><!-- icon --></svg>
  <span class="visually-hidden">Delete item</span>
</button>

Output Format

Generate reports structured as:

markdown
# Accessibility Audit Report

## Summary
- Total Issues: X
- Critical: X | Serious: X | Moderate: X | Minor: X
- WCAG Level: A, AA, or AAA
- Automated Coverage: ~57% (manual testing required)

## Critical Issues (Fix Immediately)

### 1. [Issue Name] - WCAG X.X.X
**Severity:** Critical  
**Impact:** [Who is affected and how]  
**Affected:** X elements

**Locations:**
- `path/to/file.tsx:123`
- `path/to/file.tsx:456`

**Problem:**
[Brief description]

**Fix:**
```tsx
// Before
<div onClick={handleClick}>Click me</div>

// After
<button onClick={handleClick}>Click me</button>

Why: [Accessibility principle]


Serious Issues

[Same format]

Moderate Issues

[Same format]

Testing Recommendations

  1. Manual keyboard testing (Tab, Enter, Escape)
  2. Screen reader testing (see references/screen-reader-guide.md)
  3. Automated testing setup (@axe-core/react or Lighthouse CI)
  4. Color contrast validation (WebAIM Contrast Checker)

Next Steps

[Prioritized action items]


---

## Tools & Resources

### Development Tools
- **eslint-plugin-jsx-a11y** - React/JSX static analysis (~37 rules)
- **axe-core DevTools** - Browser extension for runtime testing
- **Lighthouse** - Built into Chrome DevTools

### Testing Tools  
- **@axe-core/react** - Runtime accessibility testing
- **@axe-core/playwright** - E2E test integration
- **pa11y** - Automated command-line testing

### Manual Testing
- **WebAIM Contrast Checker** - https://webaim.org/resources/contrastchecker/
- **WAVE** - Browser extension for visual feedback
- **Screen readers** - NVDA (Windows), VoiceOver (macOS), JAWS

### Reference Docs
- `references/WCAG-criteria.md` - All WCAG 2.1 success criteria
- `references/ARIA-patterns.md` - Common ARIA patterns and examples
- `references/screen-reader-guide.md` - Testing commands and scenarios
- `references/grep-patterns.md` - Search patterns for code audits

### References
- [WebAIM Million](https://webaim.org/projects/million/) - Annual analysis of top 1M websites (violation statistics)
- [WCAG 2.1 Quick Reference](https://www.w3.org/WAI/WCAG21/quickref/) - Interactive WCAG guide
- [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/) - Official ARIA patterns
- [Deque axe Rules](https://dequeuniversity.com/rules/axe/) - All axe-core rules explained
- [jsx-a11y Rules](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules) - ESLint accessibility rules

---

## Important Notes

- Automated tools catch 30-57% of issues; manual testing required
- Pages with ARIA average 41% more errors than without
- Always test with actual assistive technology when possible
- Focus on critical issues first (keyboard, screen readers, contrast)
- Document deliberate accessibility decisions
- Test on multiple browsers and devices
- Include users with disabilities in testing when possible

## Common Pitfalls to Avoid

1. Relying solely on automated testing
2. Using ARIA when native HTML suffices
3. Removing focus indicators
4. Using positive tabindex values
5. Color as only means of conveying information
6. Keyboard traps in modals/dialogs
7. Non-descriptive link text
8. Missing or incorrect heading hierarchy
9. Unlabeled form controls
10. Missing language attributes

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Web Accessibility Audit AI skill do?

Audit web applications for WCAG accessibility compliance. Use when asked to run accessibility checks, identify common violations, and provide remediation guidance.

Why use Web Accessibility Audit on TypingMind?

Because you install it once and use it with any model. Web Accessibility Audit is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Web Accessibility Audit in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/warpdotdev/oz-skills/tree/main/.agents/skills/web-accessibility-audit. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Web Accessibility Audit?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Web Accessibility Audit?

As many as you like. As long as a model supports skills, you can use Web Accessibility Audit with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Web Accessibility Audit AI skill free?

Yes. It is published on GitHub by warpdotdev under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇