Overview
The Popover API is a browser-native mechanism for creating light-dismiss overlays — popovers that close when the user clicks outside, presses Escape, or opens another popover. It handles top-layer rendering, light dismiss, and aria-expanded toggling automatically. However, the Popover API does not add a semantic role — you must add role="dialog", role="tooltip", or another appropriate role yourself. The API reached Baseline Widely Available in April 2025, meaning it is supported across all major browsers.
WCAG Criteria:
- 4.1.2 Name, Role, Value — the popover must have an appropriate role and accessible name
- 1.4.13 Content on Hover or Focus — content triggered by user interaction must be dismissible, hoverable, and persistent
Key requirements:
- Use the
popoverattribute on the target element andpopovertargeton the invoking button - Add
role="dialog"orrole="tooltip"yourself — the Popover API does not provide semantic roles - Provide an accessible name via
aria-labeloraria-labelledby - The browser automatically handles Escape to dismiss, light dismiss (click outside), and
aria-expandedon the trigger button - Use
popover="auto"for light-dismiss behavior (closes when another auto popover opens or when clicking outside) - Use
popover="manual"when you need explicit open/close control without light dismiss
Basic Popover
Custom Toggle Div vs. Native Popover API
<!-- Custom div popover — no Escape, no light dismiss, no ARIA -->
<button onclick="togglePopover()">More Info</button>
<div id="popover" style="display:none">
<p>This feature allows you to export your data
in multiple formats including CSV, JSON, and PDF.</p>
<a href="#">Learn more about exports</a>
</div><!-- Native Popover API — Escape, light dismiss, aria-expanded -->
<button popovertarget="pop">More Info</button>
<div
popover="auto"
id="pop"
role="dialog"
aria-label="Additional information"
>
<p>This feature allows you to export your data
in multiple formats including CSV, JSON, and PDF.</p>
<a href="#">Learn more about exports</a>
</div>This feature allows you to export your data in multiple formats including CSV, JSON, and PDF.
Learn more about exportsWhat’s wrong with the custom div popover?
- No
role— screen readers treat it as generic content, not a dialog or overlay - No
aria-labeloraria-labelledby— screen readers cannot identify the purpose of the overlay - No Escape key handling — keyboard users must find and click a close button or tab away
- No light dismiss — clicking outside the popover does nothing; it stays open
- No
aria-expandedon the trigger — screen readers cannot tell whether the popover is open or closed - Manual
displaytoggling is fragile and does not handle stacking context or top-layer rendering
What the native Popover API provides:
- Escape key closes the popover automatically
- Light dismiss — clicking outside closes the popover
aria-expandedis automatically toggled on the trigger button (thepopovertargetbutton)- Top-layer rendering — the popover is promoted to the browser’s top layer, avoiding
z-indexconflicts - Auto stacking — when a new
popover="auto"opens, the previous one closes - The API does not add a semantic role — you must add
role="dialog",role="tooltip", or another appropriate role yourself
What the screen reader announces:
| Version | Announcement |
|---|---|
| Custom div | ”More Info, button” (no expanded state, popover content has no role) |
| Popover API | ”More Info, expanded, button” then “Additional information, dialog” (role and name announced) |
popover="auto" vs popover="manual":
| Behavior | auto | manual |
|---|---|---|
| Light dismiss (click outside) | Yes | No |
| Escape closes | Yes | No |
| Closes when another auto popover opens | Yes | No |
aria-expanded toggled on trigger | Yes | Yes |
| Use case | Menus, info overlays, tooltips | Toasts, persistent notifications |
Key Teaching Points
- The Popover API does not add semantic roles — adding
popover="auto"to a<div>does not make it a dialog. You must explicitly addrole="dialog",role="tooltip",role="menu", or whatever role matches the content. aria-expandedis handled automatically — the browser togglesaria-expandedon thepopovertargetbutton when the popover opens and closes.- Light dismiss solves WCAG 1.4.13 “dismissible” — content shown via the Popover API can always be dismissed by pressing Escape or clicking outside.
- Popover is not a dialog replacement — for content that requires a focus trap or blocks background interaction, use
<dialog>with.showModal(). The Popover API is for lightweight overlays that do not block the page. - Baseline Widely Available — the Popover API reached Baseline Widely Available in April 2025 and is supported in Chrome, Edge, Firefox, and Safari.