Syntic
← All skills
EngineeringFreeCommunityv1.0.0

a11y-audit

Use when auditing WCAG 2.2 Level A/AA accessibility, fixing violations in React, Next.js, Vue, Angular, Svelte, or HTML, checking color contrast, or writing accessibility compliance reports.

About this skill

Use when auditing WCAG 2.2 Level A/AA accessibility, fixing violations in React, Next.js, Vue, Angular, Svelte, or HTML, checking color contrast, or writing accessibility compliance reports.

SKILL.md

a11y-audit.SKILL.md

Place it in your Syntic skills folder. For Syntic Code, install in your local skills directory, review the contents and run it in a controlled environment first.

SKILL.md
---
name: a11y-audit
description: Use when auditing WCAG 2.2 Level A/AA accessibility, fixing violations in React, Next.js, Vue, Angular, Svelte, or HTML, checking color contrast, or writing accessibility compliance reports.
category: Engineering
version: 1.0.0
tools: []
---

# Accessibility Audit (WCAG 2.2 AA)

Audit web application code for WCAG 2.2 Level A and AA violations, produce framework-specific before/after fixes, and turn findings into a stakeholder-ready compliance report. Applies to React, Next.js, Vue, Angular, Svelte, and plain HTML codebases.

## Workflow: Scan -> Fix -> Verify -> Report

1. **Scan** - Review the code (pasted in chat or found via knowledge_base_search) against every WCAG 2.2 Level A and AA success criterion. Classify each violation by severity: Critical, Major, or Minor.
2. **Fix** - For each violation, propose the precise before/after code change, matched to the project's framework (React, Next.js, Vue, Angular, Svelte, or plain HTML).
3. **Verify** - Re-check the fixed code against the original violations to confirm they are resolved and that no new issues were introduced.
4. **Report** - Summarize findings in a structured, stakeholder-ready format: pass/fail counts by severity, remaining risk, and recommended timeline.

If the user wants ongoing protection, note that these checks can run manually before each release or be wired into a CI/CD pipeline (GitHub Actions, GitLab CI, Azure DevOps) as a merge gate - describe the gate conceptually and let the user's engineers implement it.

## Severity Classification

| Severity | Definition | Example | SLA |
|---|---|---|---|
| Critical | Blocks access for entire user groups | Missing alt text; no keyboard access to navigation | Fix before release |
| Major | Significant barrier that degrades experience | Insufficient color contrast; missing form labels | Fix within current sprint |
| Minor | Usability issue that causes friction | Redundant ARIA roles; suboptimal heading hierarchy | Fix within next 2 sprints |

## What to Check

- **Images/media (1.1.1)**: every informational `<img>` has descriptive `alt` text; purely decorative images use `alt=""`.
- **Keyboard access (2.1.1)**: every interactive element (`onClick` on a `<div>`, custom widgets) is operable via keyboard. Prefer native `<button>`/`<a>` over `role="button"` on a `<div>` - native elements get keyboard handling for free.
- **Color contrast (1.4.3)**: text must meet at least 4.5:1 contrast against its background at AA. Watch for near-misses: `#aaa` text on white is only 2.32:1, `#999` on white is only 2.85:1 - both fail.
- **Name, Role, Value (4.1.2)**: interactive elements expose an accessible name and role (via `aria-label` or `aria-labelledby`), not just a visual affordance.
- **Focus management**: a visible focus indicator on every interactive element (never `outline: none` without a `focus-visible` replacement); logical tab order; no skipped heading levels (h1 -> h3).
- **ARIA correctness**: no redundant or incorrect ARIA roles; `aria-label` for interactive elements, `aria-labelledby` for pointing at visible text.
- **Motion**: respect `prefers-reduced-motion` for animation-heavy UI.
- **WCAG 2.2's newer criteria** add requirements beyond the 2.1 baseline, including Focus Appearance and Target Size for interactive controls - check these alongside the Level A/AA baseline.

For edge cases, the WCAG 2.2 specification and the WAI-ARIA Authoring Practices are the canonical sources for exact success-criterion text and interaction patterns - use web_search to pull them when a judgment call is close.

## Example Fix Pattern (React)

Before:
```tsx
function ProductCard({ product }) {
  return (
    <div onClick={() => navigate(`/product/${product.id}`)}>
      <img src={product.image} />
      <div style={{ color: '#aaa', fontSize: '12px' }}>{product.name}</div>
      <span style={{ color: '#999' }}>${product.price}</span>
    </div>
  );
}
```

Violations: `<img>` missing `alt` (1.1.1, Critical); `<div onClick>` not keyboard accessible (2.1.1, Critical); `#aaa`/`#999` text fails 4.5:1 contrast (1.4.3, Major - actual ratios 2.32:1 and 2.85:1); interactive element missing accessible name/role (4.1.2, Major).

After:
```tsx
function ProductCard({ product }) {
  return (
    <a href={`/product/${product.id}`} className="product-card"
       aria-label={`View ${product.name} - $${product.price}`}>
      <img src={product.image} alt={product.imageAlt || product.name} />
      <div style={{ color: '#595959', fontSize: '12px' }}>{product.name}</div>
      <span style={{ color: '#767676' }}>${product.price}</span>
    </a>
  );
}
```
Swapping the clickable `<div>` for a native `<a>` fixes keyboard access and supplies an accessible name in one move; darkening the text colors clears the 4.5:1 threshold. The same pattern (native element + real label + sufficient contrast) applies in Vue, Angular, Svelte, and plain HTML - only the template syntax changes.

## Common Pitfalls

| Pitfall | Correct Approach |
|---|---|
| `role="button"` on a `<div>` | Use native `<button>` - keyboard handling included |
| `tabindex="0"` on everything | Only interactive elements need focus |
| `aria-label` on non-interactive elements | Use `aria-labelledby` pointing to visible text |
| `display: none` for screen-reader hiding | Use a visually-hidden (`.sr-only`) style instead |
| Color alone conveys meaning | Add icons, text labels, or patterns alongside color |
| Placeholder as only label | Always provide a visible `<label>` |
| `outline: none` without replacement | Always provide a visible `focus-visible` indicator |
| Empty `alt=""` on informational images | Informational images need descriptive alt text |
| Skipping heading levels (h1 -> h3) | Heading levels must be sequential |
| `onClick` without `onKeyDown` | Add keyboard support or use native elements |
| Ignoring `prefers-reduced-motion` | Wrap animation CSS in that media query |

## Manual Testing Checklist

When code review alone isn't enough, walk through manually: tab through the whole page in visual/logical order and confirm every mouse-reachable action is also keyboard-reachable; listen with a screen reader for meaningful reading order and labels; confirm text can be resized without losing content; verify every form field has a visible label and errors are tied to their field, not color alone.

## Reporting

When asked for a compliance report, structure it as: an executive summary (pass/fail counts by severity), a per-violation table (WCAG criterion, severity, location, fix status), and a remediation timeline keyed to the SLA above - Critical before release, Major within the current sprint, Minor within the next 2 sprints. Tailor depth to the audience: a PM needs the summary and timeline; a developer needs the per-violation table and code diffs.

Install

Syntic App

  1. 1Create a dedicated folder for this skill in your local skills library.
  2. 2Place SKILL.md into that folder.
  3. 3Restart Syntic and invoke this skill on matching tasks.

Syntic Code (CLI)

  1. 1Save SKILL.md in your local Syntic Code skills directory.
  2. 2Keep related files in the same skill folder.
  3. 3Run in a safe environment and validate outputs.