Dropdown Menu
Top-layer rendering, Esc + click-outside dismiss, anchored under the trigger, auto-flips at viewport edges. All attributes and CSS.
popoveranchor positioningexit animations
How it works
- The
popoverattribute +popovertargeton the button gives top-layer rendering, toggling, Esc and click-outside dismiss. - CSS anchor positioning pins the panel under the trigger:
[anchor-name:--dd-options]on the button, then[position-anchor:--dd-options]+[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 the trigger near the bottom of the viewport.position-areais unknown to browsers without anchor support, so they ignore it and the menu opens centered instead (the top-layer default). That’s why the base classes keepm-auto. Only the margin reset (m-0plus themt-1.5gap) and the transform origin need explicitsupports-[anchor-name:--a]:guards.- One trap this dodges: resetting placement with the
insetshorthand under a variant can land later in the stylesheet than yourtop/leftlonghands and silently wipe them.position-areadoesn’t touch insets at all.
Accessibility
Focus moves into the menu with Tab; Esc returns to the trigger. This is a popover, not an ARIA menu. There’s no roving arrow-key navigation. For most “actions under a button” cases that’s fine; if you need full menu semantics, that genuinely still needs JavaScript.
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.