Lena Fischer·
Ran our signup modal markup through this and it found five WCAG failures our automated scanner missed, focus trap included
Audits component markup for the WCAG failures automated scanners miss: focus management, semantics, announcements, and keyboard traps.
Deep Accessibility Audit Beyond the Scanner
You are an accessibility specialist auditing a UI component. Automated scanners (axe, Lighthouse) already ran — your job is the failures they structurally cannot catch.
Component markup (HTML/JSX):
{{markup}}
Component behavior description (what opens it, what closes it, async states): {{behavior}}
Target conformance: {{wcag_level}}
Audit specifically for:
1. **Focus management** — where does focus go when the component mounts, and where does it return on close? Is focus trapped where it should be (modal) or trapped where it shouldn't be? Can Escape always exit?
2. **Semantics vs. appearance** — divs with click handlers posing as buttons, headings chosen for size not hierarchy, lists that aren't lists.
3. **Announcements** — are async results (loading, errors, success) announced via live regions, or do they only change visually? Are error messages programmatically associated with their inputs (aria-describedby), not just adjacent?
4. **Keyboard parity** — every mouse interaction reachable and operable by keyboard, in a sensible tab order. Check for positive tabindex.
5. **Labels under stress** — icon-only buttons, placeholder-as-label, and labels that make no sense out of visual context to a screen reader user.
For each finding: WCAG success criterion violated, severity (blocker / serious / moderate), the exact element, what a screen-reader user actually experiences, and the minimal fix — prefer native elements over ARIA repairs.
End with what passes cleanly, so the team knows what NOT to touch.
Ergebnisse
## Findings — signup modal, target WCAG 2.2 AA
### Blockers
**1. No focus trap — SC 2.4.3 Focus Order**
Tab from the last input moves focus to the page behind the modal while the overlay stays visible. A keyboard user is now operating invisible controls. Screen-reader experience: reading order escapes into the page mid-form.
Fix: trap focus within the dialog while open. With native `<dialog>` + `showModal()` you get this free — you're rendering a `<div role="dialog">`, which does not trap.
**2. Focus not restored on close — SC 2.4.3**
After closing, focus lands on `<body>`. The keyboard user restarts tabbing from the page top — on your signup page that's 14 tab stops to get back.
Fix: store `document.activeElement` on open, restore it on close.
### Serious
**3. Error messages not associated — SC 3.3.1 Error Identification**
Validation errors render in a `<span class="error">` below each input, visually adjacent only. Screen reader announces nothing on error; the user submits, hears nothing, and is stuck.
Fix: `aria-describedby` linking input to its error span, plus `aria-invalid="true"` on the failing input.
**4. Submit state change is visual-only — SC 4.1.3 Status Messages**
The button swaps to a spinner; nothing is announced. On slow connections a screen-reader user hears silence for several seconds and clicks again — matching the duplicate-signup logs you mentioned.
Fix: a visually-hidden `role="status"` region announcing "Creating your account" and then the success/error outcome.
### Moderate
**5. Close button is icon-only with title attr — SC 4.1.2 Name, Role, Value**
`title="Close"` is unreliable across screen readers and invisible to touch users.
Fix: `aria-label="Close signup dialog"` — naming the dialog it closes helps when multiple dialogs exist.
## What passes cleanly — do not touch
- Heading hierarchy inside the modal (h2 → h3) is correct.
- All inputs have real `<label for>` associations — no placeholder-as-label. Rare and appreciated.
- Tab order within the form follows visual order; no positive tabindex anywhere.
- Color contrast on all text and the primary button exceeds 4.5:1 (scanner confirmed, spot-checked the disabled state too).
## Priority order
Fix 1 and 2 together (same focus-management PR), then 3 and 4 (same announcement PR), then 5. Estimated: two small PRs, no redesign needed.
Modell: Claude Opus 4.6
33 Likes21 SavesScore: 23
2 Kommentare
Emily Chen·
The duplicate-signup logs matching the silent spinner is such a good catch — a11y bugs showing up as business metrics.
Dev Patel·
What passes cleanly, do not touch — every audit should end like this. Prevents well-meaning regressions.
