Skip to content

Accessibility: modal focus trapping #39

@gregoryfoster

Description

@gregoryfoster

Summary

Extracted from #35 — modal focus trapping deferred until an actual modal component exists.

Background

  • No modals in the app today. The mobile nav drawer (base.html) already has dialog semantics (role="dialog" aria-modal="true"), Escape-to-close, and focus return.
  • STYLE.md references focus trapping as "deferred to Accessibility tier 2: modal focus, form hints, row focus #35", but building it without a consumer is YAGNI.

Recommended approach

When the first modal is needed:

  1. Reusable focus-trap.js — small utility (~30 lines):
    • Capture document.activeElement on open
    • Focus first interactive element inside the dialog
    • Cycle Tab/Shift-Tab within the modal boundary
    • Escape to close, restore focus to the saved element
  2. Wire into the mobile drawer as a first consumer (replacing its inline focus logic)
  3. Respect prefers-reduced-motion for any open/close animations
  4. Test: manual keyboard-only walkthrough + automated check that focus doesn't escape

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions