Layout Beginner

Dropdown menus without JavaScript toggles

The old way used JS for toggle, click-outside, and ESC, plus manual aria. The popover attribute and popovertarget give you a built-in dismissible popover with no toggle code.

Old 12+ lines
1.menu {
2  display: none;
3}
4.menu.open { display: block; }
5
6/* JS: toggle class, document click-outside,
7 keydown ESC, aria-expanded, aria-hidden */
Modern
5 lines
1/* HTML: <button popovertarget="menu"> ... <div id="menu" popover> */
2
3#menu[popover] {
4  position: absolute;
5  margin: 0.25rem 0;
6}
7
8/* Toggle, light dismiss, ESC: built in. */

Built-in toggle

Click the button to open, click outside or press ESC to close. No event listeners.

Top layer

Popover goes in the top layer. No z-index fights with the rest of the page.

Accessible

The platform handles focus and dismiss. You style the popover and wire the button with popovertarget.

Browser Support
92%
Chrome Firefox Safari Edge
Lines Saved
12+ → 5
No toggle or dismiss JS
Old Approach
JS toggle + aria
Click-outside, ESC, aria-expanded
Modern Approach
popover + popovertarget
Light dismiss, ESC, top layer

How it works

The old way: a click handler toggles a class that shows or hides the menu. You add a document click listener for click-outside, a keydown listener for Escape, and you manage aria-expanded and aria-hidden yourself. It's easy to miss an edge case.

The modern way: put popover on the menu element and popovertarget="menu" on the button. The button becomes a popover trigger. Opening, closing, click-outside, and ESC are built in. The menu is rendered in the top layer. You only need CSS to position and style it.

ESC