Popover
A trigger and a free-form panel in the top layer — anchored under the button, light-dismissed, focus handled. Same machinery as the dropdown menu, pointed at arbitrary content.
popoveranchor positioningexit animations
Popover vs Dropdown Menu
Both float a panel in the top layer, both anchor under a trigger, both dismiss on Esc and outside click. The difference is the contents. A Dropdown Menu is a list of actions. A popover holds whatever you want: a little form, a set of controls, a preview. When the panel has inputs and labels rather than a column of commands, reach for this.
How it works
- The
popoverattribute +popovertargeton the button give you top-layer rendering, toggling, Esc and click-outside dismiss. No JavaScript, no focus-trap library. Tab moves into the fields; Esc returns to the trigger. - CSS anchor positioning pins the panel under the button:
[anchor-name:--pop-dimensions]on the trigger, then[position-anchor:--pop-dimensions]+[position-area:block-end_span-inline-end]on the panel (“below the anchor, growing to the right”). [position-try-fallbacks:flip-block]flips the panel above when there’s no room below.- The inputs are plain
<input>s. Because the panel lives in the top layer, they focus, type and tab exactly as they would in normal flow. The popover isn’t a rendering trick that traps them.
The fallback story
Without the Popover API the panel renders in normal document flow, always visible, and the button
does nothing, so keep the markup somewhere sensible in the source order. Without anchor positioning
the popover still opens, just centered in the viewport (the top-layer default) instead of pinned to
the trigger; that’s why the base classes keep m-auto and only the offset is wrapped in a
supports-[anchor-name:--a]: guard.
Browser support
Minimum stable version per engine, resolved at build time from MDN's browser-compat-data; Baseline status from the official web-features dataset. Everything degrades gracefully — the “when missing” column is the actual behavior, not a broken page.
| Feature | Chrome | Edge | Firefox | Safari | When missing |
|---|---|---|---|---|---|
| Popover APIBaseline 2025 · newly available | 114 | 114 | 125 | 17 | Content renders in normal document flow, always visible, and the trigger does nothing. |
| CSS anchor positioningLimited availability | 129 | 129 | 147 | 26 | The popover opens centered in the viewport (the top-layer default) instead of attached to its trigger. |
| Entry/exit animations (allow-discrete + @starting-style)†Baseline 2024 · newly available | 117 | 117 | 129 | 17.5 | Elements appear and disappear instantly. Nothing breaks — you just lose the animation. |
† @supports cannot test at-rules, so the badge checks transition-behavior: allow-discrete, which co-shipped with @starting-style in every engine.