Web Accessibility Audit and Remediation Guide

Conduct a comprehensive WCAG 2.2 web accessibility audit with prioritized remediation steps, code fixes, and testing strategies to make your website or app accessible to all users.

Prompt Template

You are a senior web accessibility consultant (IAAP certified) with deep expertise in WCAG 2.2 standards, assistive technology testing, and accessible front-end development. Conduct a comprehensive accessibility audit and create a remediation plan for my web application.

**Application Type:** [e.g., SaaS dashboard, e-commerce store, content site, mobile web app]
**Tech Stack:** [e.g., React + TypeScript, Next.js, Vue, WordPress, vanilla HTML/CSS/JS]
**UI Library:** [e.g., Material UI, Tailwind + Headless UI, Chakra UI, custom components, none]
**Current Accessibility State:** [never audited / partially compliant / has known issues / recently redesigned]
**Target Compliance Level:** [WCAG 2.2 Level A / Level AA / Level AAA]
**Key User Flows to Audit:** [list 3-5 critical flows — e.g., signup, checkout, search & filter, dashboard navigation, form submission]
**Known Issues (if any):** [e.g., images missing alt text, color contrast fails, keyboard navigation broken in modals]
**Legal Requirements:** [e.g., ADA compliance needed, EU Accessibility Act, Section 508, none specific]

Please provide:

1. **Audit Framework** — Systematic checklist organized by WCAG principle (Perceivable, Operable, Understandable, Robust) with specific success criteria to test for each user flow

2. **Common Issues by Component** — For each UI component type in my stack, list the most common accessibility failures and their fixes:
   - Navigation menus & dropdowns
   - Modal dialogs
   - Forms & validation
   - Data tables
   - Tabs & accordions
   - Carousels/sliders
   - Toast notifications
   - Custom select/combobox

3. **Code-Level Remediation Guide** — For each issue found, provide:
   - The WCAG success criterion violated
   - Before code (inaccessible)
   - After code (accessible)
   - Why the fix works
   - How to test it

4. **Testing Strategy**
   - Automated testing tools setup (axe-core, Lighthouse, eslint-plugin-jsx-a11y)
   - Manual testing checklist (keyboard navigation, screen reader, zoom)
   - Screen reader testing guide (VoiceOver, NVDA, JAWS — basic commands)
   - CI/CD integration for automated a11y testing

5. **Prioritized Remediation Roadmap**
   - P0 (critical): Blocks users entirely
   - P1 (high): Major usability barriers
   - P2 (medium): Degraded experience
   - P3 (low): Best practices and enhancements

6. **Accessible Component Patterns** — Production-ready code snippets for the 5 most commonly broken components in my tech stack

Example Output

# Web Accessibility Audit & Remediation Plan

**App:** SaaS Dashboard (React + TypeScript + Tailwind + Headless UI)

**Target:** WCAG 2.2 Level AA


1. Audit Checklist — Signup Flow

| # | WCAG Criterion | What to Check | Method |

|---|---------------|---------------|--------|

| 1.1 | 1.1.1 Non-text Content | All images, icons, and SVGs have meaningful alt text or are marked decorative | Manual + axe |

| 1.2 | 1.3.1 Info and Relationships | Form labels are programmatically associated with inputs (not just visually) | axe + screen reader |

| 1.3 | 1.3.5 Identify Input Purpose | Form fields use `autocomplete` attributes for name, email, password | Code review |

| 1.4 | 1.4.3 Contrast (Minimum) | All text meets 4.5:1 ratio (3:1 for large text) | Lighthouse + manual |

| 1.5 | 2.1.1 Keyboard | Entire signup flow completable with keyboard only (Tab, Enter, Escape) | Manual keyboard test |

| 1.6 | 2.4.7 Focus Visible | Focus indicator visible on all interactive elements | Manual + CSS review |

| 1.7 | 3.3.1 Error Identification | Validation errors announced to screen readers and identify the field | Screen reader test |

| 1.8 | 3.3.2 Labels or Instructions | All fields have visible, persistent labels (not just placeholders) | Visual + code review |

| 1.9 | 4.1.2 Name, Role, Value | Custom components expose correct ARIA roles and states | axe + screen reader |

2. Common Issues — Modal Dialog

❌ Inaccessible Modal

// BAD: div acting as modal, no focus trap, no ARIA

<div className="modal-overlay" onClick={close}>

<div className="modal">

<span className="close-btn" onClick={close}>×</span>

<h2>Confirm Deletion</h2>

<p>Are you sure?</p>

<button onClick={onDelete}>Delete</button>

</div>

</div>

Issues:

- No `role="dialog"` or `aria-modal="true"`

- No `aria-labelledby` pointing to the heading

- No focus trap — Tab key exits the modal into background content

- Close "button" is a `<span>` — not keyboard accessible

- No focus return when modal closes

- Background content not marked `aria-hidden`

✅ Accessible Modal

import { Dialog } from '@headlessui/react'

<Dialog open={isOpen} onClose={close} className="modal-overlay">

<div className="fixed inset-0 bg-black/30" aria-hidden="true" />

<div className="modal-container">

<Dialog.Panel className="modal">

<Dialog.Title>Confirm Deletion</Dialog.Title>

<Dialog.Description>This action cannot be undone.</Dialog.Description>

<p>Are you sure you want to delete this project?</p>

<div className="flex gap-3">

<button onClick={close}>Cancel</button>

<button onClick={onDelete} className="btn-danger">Delete project</button>

</div>

</Dialog.Panel>

</div>

</Dialog>

**Why it works:** Headless UI's Dialog component automatically handles `role="dialog"`, `aria-modal="true"`, focus trap, focus return, and Escape key closing. You get WCAG compliance for free.

3. Forms & Validation

❌ Before: Placeholder-Only Labels

<input type="email" placeholder="Email address" className="input" />

{error && <span className="text-red-500 text-sm">{error}</span>}

✅ After: Proper Labels + Accessible Errors

<div>

<label htmlFor="email" className="block text-sm font-medium">

Email address

</label>

<input

id="email"

type="email"

autoComplete="email"

aria-describedby={error ? 'email-error' : undefined}

aria-invalid={error ? 'true' : undefined}

className="input"

/>

{error && (

<p id="email-error" role="alert" className="text-red-500 text-sm mt-1">

{error}

</p>

)}

</div>

**Criteria fixed:** 1.3.1 (label association), 1.3.5 (autocomplete), 3.3.1 (error identification), 3.3.2 (labels)

4. Testing Strategy

Automated Testing Setup

npm install -D axe-core @axe-core/react eslint-plugin-jsx-a11y

ESLint config (catches issues at dev time):

{

"extends": ["plugin:jsx-a11y/recommended"]

}

CI/CD Integration (GitHub Actions):

- name: Accessibility Audit

run: npx @axe-core/cli http://localhost:3000 --exit

Manual Testing Checklist

- [ ] Complete every key flow using only keyboard (no mouse)

- [ ] Tab order follows logical reading order

- [ ] All interactive elements have visible focus indicators

- [ ] Test at 200% browser zoom — no content overflow or loss

- [ ] Test with VoiceOver (Mac: Cmd+F5) on signup and checkout flows

- [ ] Verify all images have meaningful alt text (or alt="" for decorative)

- [ ] Check color contrast with browser DevTools (≥4.5:1)

5. Prioritized Roadmap

| Priority | Issue | WCAG | Affected Flow | Effort |

|----------|-------|------|---------------|--------|

| P0 | Modal has no focus trap | 2.1.2 | Delete confirmation | 2h |

| P0 | Form errors not announced | 3.3.1 | Signup, checkout | 3h |

| P1 | Missing visible focus styles | 2.4.7 | All flows | 4h |

| P1 | Images missing alt text | 1.1.1 | Dashboard, listings | 2h |

| P2 | Low contrast on muted text | 1.4.3 | Throughout | 3h |

| P2 | Custom select not keyboard-operable | 2.1.1 | Filters, settings | 6h |

| P3 | Add skip-to-content link | 2.4.1 | All pages | 1h |

Tips for Best Results

  • 💡Start with automated tools (axe-core, Lighthouse) to catch the low-hanging fruit — they find ~30-40% of issues instantly. But NEVER rely on automated testing alone; manual keyboard and screen reader testing catches the other 60%.
  • 💡Use your framework's accessibility-focused component libraries (Headless UI, Radix, React Aria) instead of building custom components. They handle ARIA roles, keyboard navigation, and focus management correctly out of the box.
  • 💡The highest-impact fix for most sites is proper form labeling. Screen readers can't guess what an input is for — every field needs a programmatic label, not just a placeholder.
  • 💡Add accessibility testing to your CI/CD pipeline with axe-core. Catching regressions automatically prevents accessibility debt from accumulating sprint over sprint.