The Popover API: A Quick Tour of Visibility Control
The Popover API has quietly landed in all modern browsers, giving developers a standards-based way to toggle element visibility without writing JavaScript state management. It's a feature we've been tracking since the early days of the <dialog> element discussions, but only recently did it reach full cross-browser support.
Interestingly, the original plan was a dedicated <popover> element. Chromium experimented with that approach well into 2021 before dropping it in favor of a popover attribute. That decision makes sense: any element can be a popover, so an attribute is more flexible than a new tag.
<div popover>
<!-- Stuff -->
</div>
When Visibility Disappears
Consider a simple element you might want to use as a popover:
<div>👋</div>
Without any extra attributes, that emoji displays normally. Add the popover attribute, and it vanishes from view. This is often the first surprise for developers—it looks like a bug, but DevTools confirms it's the intended behavior. The element is hidden until something triggers it.
Multiple popovers on a page are distinguished with IDs:
<div popover id="tooltip">
<!-- Stuff -->
</div>
<div popover id="notification">
<!-- Stuff -->
</div>
Triggering a popover requires a second attribute. Any <button> or <input>-style button can become the trigger:
<button popovertarget="wave">Say Hello!</button>
<div popover id="wave">👋</div>
With that pairing, clicking the button toggles the popover's visibility.
Default Styling and Overrides
Once the popover opens, you'll notice a thick black border around it—that's a browser default. Even without any custom CSS, other interesting behaviors emerge. The element sizes to its content and centers itself on the page, despite computing as display: block.

Removing that default border isn't as straightforward as declaring no border on the element:
/* Nope 👎 */
#wave {
border: 0;
}
The reason is the :popover-open pseudo-class. It matches the popover element only in its open state, meaning its styles override those declared on the base element selector. Alternatively, you can target the attribute itself:
/* Select all popovers on the page */
[popover] {
border: 0;
}
/* Select a specific popover: */
#wave[popover] {
border: 0;
}
/* Same as: */
#wave:popover-open {
border: 0;
}
Beyond Basic Toggling
This opens up possibilities for animations. You can attach transitions or keyframe animations to the :popover-open state, making the appearance feel more polished.
Popovers also support the ::backdrop pseudo-element, similar to <dialog>. This lets you place a styled overlay behind the popover to draw focus or obscure the page content behind it.
The implications for UI patterns are significant. Tooltips and "toggletips"—elements that toggle visibility on click rather than hover—become much simpler. Combined with CSS Anchor Positioning, which is gaining browser support, popovers promise more precise placement without relying on magic numbers for positioning.
The API's flexibility extends beyond traditional popovers. You can repurpose it for any visibility toggle: slide-out menus, custom dropdowns, or other interface elements that traditionally require JavaScript. The Popover API provides the logic; developers bring the presentation.
For deeper dives, several resources are worth bookmarking:
- On popover accessibility: what the browser does and doesn't do (Hidde de Vries)
- If you're using popover, also use the dialog element for your modal dialogs (Hidde de Vries)
- Open UI and the Popover API (Brecht De Ruyte)
- Brief Note on Popovers with Dialogs (Adrian Roselli)
- Advanced Form Control Styling With Selectmenu And Anchoring API (Brecht De Ruyte)
- Using the Popover API for HTML Tooltips (Chris Coyier)
- Comparing the Popover API and the <dialog> element (LogRocket)



