Educational guide to the Popover API
Content above the page, without blocking it
Learn to connect buttons and panels with HTML, choose dismissal rules, and preserve an accessible interaction. Then adjust the behavior and code in the playground.
Mental model
Popover is a presentation behavior. It is neither a new HTML element nor menu or modal semantics.
- 1 · InvokerThe button references the panel ID through popovertarget.
- 2 · DocumentThe content and button keep their place in the DOM; the rest of the page remains available.
- 3 · Top layerThe open panel is painted above ordinary content, outside its stacking contexts.
The browser manages the top layer. When opened, the panel leaves normal visual flow and is not clipped by its ancestors' overflow. You do not need to compete with z-index, and its DOM position does not change. Layer order also matters within the top layer.
A popover is non-modal: it does not make the rest of the document inert or trap focus. It can display help, actions, or supplemental content. If users must complete or cancel a task before continuing, choose a modal dialog.
Declarative invocation
An ID and two button attributes are enough to show and hide content without JavaScript listeners.
The popovertarget value is the ID, without #. popovertargetaction accepts toggle, show, or hide; omitting it defaults to toggle. Use type="button" so the control does not submit a form. An empty popover attribute means auto.
Supplemental help with light dismiss
The recipe applies positioning and reveals buttons inside @supports selector(:popover-open). When the browser ignores the attribute, the aside remains readable in normal flow. The fallback is inline content, without simulating light dismiss or the top layer. Opening and dismissal are native; only the manual reference adds JavaScript to restore focus.
commandfor and command can also invoke popovers using toggle-popover, show-popover, and hide-popover. They are another API with separate support. This recipe uses popovertarget to teach Popover's specific association without depending on those commands.
Modes and dismissal rules
Choose a mode based on content lifetime and the exit it needs to provide, rather than its appearance.
popover="auto"
Light dismiss and close requests, such as Escape. Opening another independent auto popover usually closes the previous one; nested popovers can stay open together. Use it for a panel that should disappear when the user continues outside.
popover="hint"
Help subordinate to auto. Showing a hint does not close the open auto popover; it replaces other independent hints and supports light dismiss and close requests. Check its availability separately.
popover="manual"
Explicit dismissal through a button or API. Outside clicks and Escape do not close it natively. Multiple manual popovers can coexist; each needs a clear exit and should not obscure essential content.
hint does not open on hover automatically. The mode defines coexistence and dismissal rules; invocation needs code or another supported API. Also, clicking an invoker outside an open auto popover can light-dismiss it even when the target is hint. Do not make necessary information available only on pointer hover.
A reference that stays open
showPopover(), hidePopover(), and togglePopover() let you coordinate a panel with application logic. beforetoggle precedes the change and toggle reports it through oldState/newState. Toggle events may be coalesced during rapid changes; do not treat them as a log of every call. The method alone does not provide the declarative button's implicit ARIA relationship.
JavaScript API reference
A snippet for the auto panel above: it defines operations to call from your logic and observes the final state. It is not executed in this guide and adds no listeners to the native buttons.
Focus and pattern choice
The platform handles part of the interaction; content structure and purpose remain the interface's responsibility.
With popovertarget, the browser sets an implicit aria-expanded/aria-details relationship and places open content after the invoker in Tab order. This is not a focus trap. In auto, pressing Escape from inside allows focus to return to the invoker; an outside click may focus the clicked destination. manual does not guarantee that restoration: the example adds a local toggle listener to return focus to the button on dismissal.
Without an autofocus target, opening a popover does not imply focusing the first control. The auto help leaves focus on the invoker; the manual reference deliberately moves it to the close control. Choose a useful initial focus and test content reading and return behavior, avoiding unnecessary jumps.
popover does not turn a div into a menu or tooltip. Here we use an aside with an associated heading for supplemental content and buttons with visible names. A role="menu" menu needs the complete keyboard and role pattern; a tooltip needs its own descriptive relationship and must not contain interactive controls.
Popover
Temporary overlaid content that lets users keep using the page: supplemental help, options, or actions. The mode determines when it disappears.
dialog
A dialog represents a dialog window. showModal() opens it in the top layer and makes the rest of the document inert; show() opens a non-modal one. Choose the variant that fits the task.
details
Content revealed in normal flow through a native summary: additional explanation or frequently asked questions. Open content participates in layout without requiring an overlay.
Styling and positioning
First preserve opening, reading, and dismissal. Then adjust presentation without changing the meaning of the pattern.
The browser hides a closed popover with display:none. Do not force display:block or grid in the closed state. Use :popover-open for open-state styles; if you need an internal layout, apply grid or flex to a wrapper inside the panel.
Default positioning is usually centered: popover does not place the panel next to the button by itself. The recipe keeps a viewport-constrained center, maximum height, and internal scrolling. To tether it to the invoker, evaluate CSS anchor positioning and edge alternatives with separate support checks; keep usable positioning as a fallback.
::backdrop represents the decorative layer immediately behind the popover. The recipe leaves it transparent. Darkening it does not make the panel modal; it may suggest blocking that does not exist. Check contrast, outside controls, and reading of content that remains relevant.
The examples add no animation. If you animate entry and exit, review @starting-style, display/overlay, and transition-behavior:allow-discrete as separate pieces. Keep a prefers-reduced-motion alternative and do not delay access to the close control for a visual effect.
Common mistakes
Connect the symptom to the failing contract before adding JavaScript.
The button does not open the panel
- Expected result
- The associated button toggles or shows its popover.
- Cause
- The target includes #, does not match the ID, is duplicated, or lacks the popover attribute.
- Solution
- Use a unique ID and that exact popovertarget value, without #. Inside forms, specify type="button" and check support.
The panel appears while closed
- Expected result
- Content overlays the page only when the native state is open.
- Cause
- An author rule overrides display:none, or the presence of the attribute is mistaken for the open state.
- Solution
- Preserve the browser's display and apply layout to a wrapper. Check state through :popover-open, rather than [popover] or an open attribute.
Escape does not close the reference
- Expected result
- The chosen mode provides the exit users need.
- Cause
- manual does not support auto's close requests or light dismiss. An unrecognized hint is also interpreted as manual in a browser with Popover.
- Solution
- Provide an accessible hide button. Use auto when you want light dismiss, and check hint compatibility before relying on its rules.
A visual menu does not work with the keyboard
- Expected result
- Interaction and accessible names match the content.
- Cause
- role="menu" was added assuming popover implemented arrow keys, items, and focus management.
- Solution
- Keep native links or buttons for a simple list of actions, or implement the full menu pattern when the product needs it.
The panel obscures its exit or sits far from the button
- Expected result
- Content and its exit remain visible on a narrow screen.
- Cause
- Top layer is confused with automatic positioning, or a fixed height cannot accommodate enlarged text.
- Solution
- Constrain size to the viewport, allow internal scrolling, and check the close control at 320 px and 200% text. Treat anchor positioning as a separate enhancement.
Support and compatibility
Check the core and the extensions your recipe uses; accepting an attribute does not validate the entire interaction.
Web Platform DX classifies Popover as Newly Available since January 27, 2025. The overall date is not each method or selector's date; the lab and examples do not certify every engine or assistive technology.
popover="hint" is listed as Limited availability in the October 8, 2026 consultation. When Popover exists but hint is unrecognized, the invalid value falls back to manual: you lose light dismiss and hint coexistence. Preserve an explicit exit or choose auto if those rules are necessary.
Detect the core with 'popover' in HTMLElement.prototype. For hint, create a test element, set its popover property to 'hint', and check that it returns 'hint', rather than 'manual'. Detection does not replace behavior tests; command/commandfor, source, interest invokers, anchors, and transitions have their own support.
If the overlay is only a convenience, keep content accessible in normal flow, as here, or use details when it fits the purpose. If it is essential, choose between a tested fallback and a compatible implementation. A handmade fixed panel does not reproduce the top layer or its focus and dismissal rules by itself.