A button that reveals a menu of options. Based on daisyUI’s dropdown, which itself supports three implementation strategies — starting with the native, zero-JS one.
Pseudocode
Structure
A wrapper (.dropdown) holds a trigger (a button, or a <summary>) and a menu (.dropdown-content), positioned relative to it.
The menu is hidden by default and only appears — and only then can be clicked — while open.
Style
.dropdown { position: relative; } so the menu can be position: absolute and anchored to it, rather than pushing the rest of the page around.
The menu needs a z-index above surrounding content, plus a shadow or border to read as “floating” above the page.
Features
Opening/closing can be entirely native: <details>/<summary> needs nothing else, exactly like the accordion note.
A more common real-world need — closing when the visitor clicks outside, or presses Escape — needs JS with the two techniques above, since neither <details> nor CSS :focus-within do that on their own. The Popover API does both natively too (third variant below) — once dismissal is free, positioning relative to the trigger is the only thing left to solve, which is where anchor positioning comes in.
Basic dropdown (<details>, no JS)
Same trick as the accordion note: <details>/<summary> opens and closes on its own. The one limitation worth knowing: clicking outside the dropdown doesn’t close it — only clicking the summary again does. The next section fixes that with a little JS.
A plain button and menu, toggled with JS instead of relying on <details>. Two listeners on document handle the parts the browser doesn’t do for free: a click anywhere outside the dropdown closes it (root.contains(e.target) tells us whether the click was inside), and Escape closes it and returns focus to the trigger.
Dropdown with Popover API + anchor positioning (no JS)
popovertarget on the button wires up open/close/outside-click/Escape entirely natively — no document listeners needed, and no .dropdown { position: relative } wrapper either. The one thing the Popover API doesn’t do on its own is position the menu next to its trigger: opening a popover promotes it to the top layer, so it renders outside normal document flow, and a relatively-positioned ancestor no longer has any effect on it. That’s exactly the gap CSS anchor positioning fills — anchor-name on the trigger, position-anchor on the popover, then top/left: anchor(...) place it relative to the button as if it had never left the flow.
Support caveat (Progressive enhancement)
As of summer 2026, the Popover API alone is broadly supported, but this combination also needs anchor positioning, which is newer. Without it, the menu still opens and closes correctly — it just won’t be positioned next to the button, falling back to the browser’s default (roughly centered) popover placement. Can I Use: anchor positionning MDN: position-anchor