Popovers and action menus
Open a popover with HTML
Connect a task action button to top-layer content with popover and popovertarget before adding JavaScript.
A small panel of secondary task actions should sit above surrounding cards, dismiss on an outside click, and close on Escape. The Popover API gives you that without an overlay library or a z-index war.
Add popover to the panel and point a button’s popovertarget at its ID. The browser creates the invoker relationship and toggles the panel. The popover starts hidden, enters the top layer when shown, and uses the default auto behavior.
<button type="button" popovertarget="task-actions">More actions</button>
<div id="task-actions" popover>
<button type="button" data-action="duplicate">Duplicate task</button>
<button type="button" data-action="archive">Archive task</button>
</div>
This declarative version works with no application JavaScript. Click More actions and the panel opens above the card. Click outside or press Escape and it closes.
Use popovertargetaction="show", hide, or toggle when the default toggle is not specific enough. Script can call showPopover(), hidePopover(), or togglePopover() when state drives the UI.
Popover describes display behavior, not the meaning of everything inside it. Keep real buttons as buttons and links as links. Do not add role="menu" just because the panel looks like a menu. That ARIA pattern brings a different keyboard contract you would then have to implement.
Top-layer placement fixes clipping and stacking. It does not pick a visual anchor for you. CSS anchor positioning can help where supported. Fixed or inset positioning is a simpler fallback. Interaction should stay usable even if the panel lands in a less elegant place.
Try this inside a card with overflow: hidden and confirm the open panel is not clipped. Open it with the keyboard, press Escape, and click outside it. If the panel is visible on first load, check whether your CSS overrides the browser hidden state instead of styling :popover-open.
Lesson completed