Count what a “simple” dropdown actually requires: click-outside detection, Escape handling, z-index warfare with every stacking context between it and the viewport, focus management, and a positioning library. Fifty kilobytes and a rendering bug later, you have a menu.

The Popover API moves all of it into the platform. Two attributes, zero JavaScript:

<button popovertarget="menu">Options</button>

<div id="menu" popover>
  <a href="/settings">Settings</a>
  <a href="/logout">Log out</a>
</div>

What you get for free

The top layer. Popovers render above everything—no z-index value can beat them, because they exit the stacking context system entirely. The decade-long war with overflow: hidden ancestors is simply over.

Light dismiss. Click outside, press Escape, open another popover—the browser closes it, consistently, with no listeners. And because it is a platform primitive, screen readers announce it correctly by default.

“The top layer is the first z-index that cannot lose.”

Styling the states

Style the open state via :popover-open, and animate entry/exit with @starting-style plus transition-behavior: allow-discrete—the pair that finally makes display-none-to-visible transitions animatable. Pair it with CSS anchor positioning to pin menus to their triggers, and the last excuse for the positioning library disappears. Semantics, accessibility, and stacking—solved in markup.