๐ŸŽฎ Two attributes, a real popover

The card below is a native popover โ€” wired with just <button popovertarget> + popover="auto". No JavaScript for open/close, click-outside dismiss, Escape, or z-index. The log shows the browser's own toggle events. Everything you touch here is the real feature.

1 ยท Open it, then dismiss it three ways

Click Open settings. Then close it however you like: click the button again, click anywhere outside, or press Esc. Watch the log in panel 3 name each event.

Settings

A plain <div popover> in the top layer โ€” above every stacking context.

Dark mode
Email notifications
Compact rows

Reset to defaults?

This popover opened from inside the other one โ€” both stack in the top layer, and there isn't a single z-index in this demo.

2 ยท Feel the two knobs

Dismiss mode

auto: click outside or press Esc to dismiss, and only one auto popover is open at a time.

Entrance

Off = the popover snaps in instantly. On = it fades and slides โ€” the whole animation is one @starting-style block, no keyframes. Reopen the popover after toggling to see the difference.

3 ยท The browser is doing the work

state: CLOSED popover= auto

Each line is a native toggle event โ€” the same event you'd listen to in real code. You wrote none of the dismiss logic.

4 ยท What you used to write vs. now

the old way
// state + a click-outside listener
const [open, setOpen] = useState(false);
useEffect(() => {
  const h = (e) => {
    if (!ref.current?.contains(e.target))
      setOpen(false);
  };
  document.addEventListener('mousedown', h);
  return () => document
    .removeEventListener('mousedown', h);
}, []);
/* + Escape handler + aria-expanded
   + position:absolute; z-index:9999 */
now
<button popovertarget="menu">
  Options
</button>

<div id="menu" popover>
  โ€ฆ
</div>

// open/close, click-outside,
// Escape, top layer, aria-expanded
// โ€” all free. Zero JavaScript.

Baseline 2024 (Chrome 114, Firefox 125, Safari 17). What the API doesn't do: viewport-aware positioning โ€” this card just uses the browser's default centering. For dropdowns that flip and shift you still reach for Floating UI or CSS Anchor Positioning.