Code example
Common baseline
aria-expanded on the trigger
The trigger button must reflect the open state via aria-expanded="true/false".
aria-haspopup and aria-controls on trigger
Use aria-haspopup="dialog" (or "true") and aria-controls referencing the popover id.
Focus management on open
Move focus to the first focusable element inside the popover when it opens.
Close with Escape
Pressing Escape must close the popover and return focus to the trigger.
Use dialog role inside popover
If the popover contains interactive controls, use role="dialog" with an accessible name.
Close on background click
Clicking outside the popover should close it.
Trap focus within popover
If the popover contains multiple focusable elements, consider implementing a focus trap.
Do not open popover on hover only
Popovers must also be accessible via keyboard (button click).
Do not put critical information in popover only
Important content placed only in a popover may be missed by users who cannot activate it.
Design system implementations
Additional checks
Connect trigger and popover with aria-describedby
Set aria-describedby={popoverId} on the trigger button (only when open) and match it to the Popover id. This lets screen readers understand the association.
Focus management must be implemented manually
Unlike Modal, MUI Popover does not provide a focus trap. If the popover contains interactive content, move focus into the popover on open and implement focus management yourself.
Code sample
Implementation notes
- –MUI Popover automatically closes on Escape key and outside click, and restores focus to the trigger.
- –Set aria-describedby on the trigger conditionally (open ? id : undefined) to avoid stale references when closed.
- –Add role="dialog" and aria-label to the inner container for popovers containing interactive content.