HTML Popover API: Live Playground and Reference

Add the popover attribute to any element and point a button at it with popovertarget="id", and the browser handles opening, closing, the top layer and Escape for you with no JavaScript. In scripts, call showPopover(), hidePopover() or togglePopover(), and listen for beforetoggle and toggle events. popover="auto" closes when you click outside; manual does not.

Popover types
ValueClick outside or Escape closes itOther popovers
popover or popover="auto"YesOpening one closes other auto popovers, except its ancestors
popover="manual"No, close it yourselfAny number can be open at once
popover="hint"YesCloses other hint popovers that are not its ancestors; meant for tooltips

Updated

Popovers used to mean a positioning library, a click-outside handler and a z-index fight. The Popover API moves all of that into HTML. The playground below creates a real popover in your browser so you can switch its type, drive it from code and watch the events fire in order.

Popover playground

Your browser runs a real popover here: switch its type, call its methods and read the event log.

Popover API reference

Attributes, methods, events and selectors
NameKindWhat it does
popoverGlobal attributeMakes the element a popover: auto, manual or hint
popovertargetAttribute on button or inputId of the popover the control opens and closes
popovertargetactionAttribute on button or inputtoggle (default), show or hide
showPopover()MethodAdds the popover to the top layer
hidePopover()MethodRemoves it from the top layer and hides it
togglePopover()MethodShows it if hidden, hides it if shown
beforetoggleEventFires before the state changes; has oldState and newState
toggleEventFires after the state changes; has oldState and newState
:popover-openCSS pseudo-classMatches a popover while it is showing
::backdropCSS pseudo-elementThe layer behind a shown popover

Popover examples with no JavaScript

These frames run with scripts switched off, and the popovers still work, because the behaviour comes from HTML.

An auto popover menu

Click the button, then click elsewhere or press Escape. The menu closes itself.

<style>
  [popover] { border: 1px solid #cbd5e1; border-radius: 10px; padding: 8px 12px; box-shadow: 0 8px 24px rgb(0 0 0 / .12) }
  [popover]:popover-open { display: grid; gap: 4px }
</style>
<button popovertarget="menu">Open menu</button>
<div id="menu" popover>
  <a href="#">Profile</a>
  <a href="#">Settings</a>
  <a href="#">Sign out</a>
</div>

A manual toast with separate show and hide buttons

Clicking outside does nothing here. Only the hide button closes it.

<style>
  #toast { margin: auto 16px 16px auto; background: #0f172a; color: #fff; border: 0; border-radius: 10px; padding: 10px 14px }
</style>
<button popovertarget="toast" popovertargetaction="show">Save</button>
<button popovertarget="toast" popovertargetaction="hide">Dismiss</button>
<div id="toast" popover="manual">Changes saved</div>

Dim the page behind a popover

::backdrop styles the layer under the popover. It is still not modal; the page behind can be clicked to close it.

<style>
  #info::backdrop { background: rgb(15 23 42 / .4) }
  #info { border: 0; border-radius: 12px; padding: 16px; max-width: 220px }
</style>
<button popovertarget="info">What is this?</button>
<div id="info" popover>A short explanation that closes when you click away.</div>

Driving a popover from JavaScript

Methods, events and feature detection

Check support before calling the methods, then read newState in the toggle event.

const tip = document.querySelector("#tip");
const supported = HTMLElement.prototype.hasOwnProperty("popover");

if (supported) {
  tip.addEventListener("beforetoggle", (e) => {
    if (e.newState === "open") tip.textContent = "Loaded at " + new Date().toLocaleTimeString();
  });
  tip.addEventListener("toggle", (e) => console.log(e.oldState, "->", e.newState));
  document.querySelector("#show").addEventListener("click", () => tip.showPopover());
  document.querySelector("#hide").addEventListener("click", () => tip.hidePopover());
}

Declarative first

Most popovers need no script at all. The button and the popover are linked by id, and the browser wires up the toggling, light dismiss and the Escape key.

Reach for showPopover() and its siblings when the trigger is not a button, such as opening a hint after a failed form check or closing a toast on a timer.

Menus, toasts and tips

Auto fits menus and pickers that should vanish when attention moves elsewhere. Manual fits notifications that stack and stay until dismissed. Hint is aimed at hover and focus tooltips.

Whatever the type, keep the content short and make sure every action inside it can also be reached by keyboard.

How it works

  1. Choose auto, manual or hint for the popover in the playground.
  2. Open it with the declarative button, or call the three methods with the script buttons.
  3. Click outside or press Escape to see which types close by themselves.
  4. Read the event log: beforetoggle fires first, then toggle, each with oldState and newState.

Tips

Frequently asked questions

Which browsers support the Popover API?

MDN marks the Popover API as Baseline newly available since January 2025, meaning it works in the latest versions of the major browsers. Some newer parts, such as the hint value, may have narrower support, so check the compatibility table before relying on them.

What is the difference between auto and manual popovers?

An auto popover light dismisses: clicking outside it or pressing Escape closes it, and opening it closes other auto popovers. A manual popover stays open until a button or script closes it, and several can be open together, which suits toasts.

Does Escape close every popover?

Escape closes auto and hint popovers, the same ones that close on a click outside. A manual popover ignores both, so it needs its own close button or a hidePopover() call.

How do I know when a popover opens or closes?

Listen for the toggle event on the popover element. Its newState is "open" or "closed". The beforetoggle event fires just before the change, which is the place to prepare content.

Where does a popover appear by default?

In the centre of the viewport, with fixed positioning, in the top layer. Move it with your own CSS, or with anchor positioning where the browser supports it.

Related: JavaScript accordion and tabs, JavaScript event listeners, CSS z-index and stacking, aria-label examples, CSS selectors cheat sheet.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap