The Labs / Frontend
FrontendWorking~6h
Accessible Modal with a Real Focus Trap
An ARIA-compliant modal dialog component with a correct focus trap: focus moves into the dialog on open, cycles only among its focusable elements on Tab/Shift+Tab, closes on Escape, and restores focus to the exact triggering element on close — validated against axe-core and a real screen reader, not just visual inspection.
What it proves
The line you can defend in an interview.
Résumé line
Implemented a WCAG 2.2-compliant modal dialog (ARIA dialog pattern, focus trap, focus restoration) with automated axe-core scans and NVDA/VoiceOver manual verification scripts, eliminating a common accessibility failure class.
- understands ARIA authoring practices, not just aria-* attribute copy-paste
- can build and verify keyboard-only interaction paths
- tests accessibility with real assistive tech, not just linters
The brief
What you build, step by step.
- 01Implement role="dialog" with aria-modal="true", aria-labelledby, and correct focus-trap logic (Tab/Shift+Tab cycle within dialog only)
- 02Move focus to the first focusable element (or a specified initial-focus target) on open, and restore focus to the exact element that triggered the modal on close
- 03Close on Escape key and on backdrop click, both dispatching the same onClose contract
- 04Prevent background content interaction and screen-reader access via inert or aria-hidden on siblings while open
- 05Support nested/stacked modals without breaking focus trap or restoration order
- 06Zero critical/serious axe-core violations across open, focused, and closed states
The proof
It’s done when these pass.
Playwright test drives the dialog with keyboard only (Tab, Shift+Tab, Escape) and asserts focus never escapes the trap and returns to the trigger on close
automated test
Automated axe-core scan run in CI against open and closed states with zero critical/serious violations
automated test
Manual screen reader walkthrough (NVDA or VoiceOver) recorded/scripted confirming the dialog is announced correctly and content outside is not reachable
artifact
Code review verifies no reliance on autofocus alone and correct handling of dynamically added/removed focusable children
reviewed
Stack
ReactTypeScriptaxe-corePlaywrightNVDA/VoiceOver manual test scripts
Sage Method
frame → decide → prove
You keep
Reusable accessible Modal component with axe-core CI gate and a documented manual screen-reader test script