Sandbox
The dropdown menu
The trap I flag most often in audits of a navigation bar is a role="menu", which makes it pass for the menu of a desktop app. With the popover attribute, your list closes with Escape and with a click elsewhere, and the browser exposes the expanded state of the button.
- Built with
- popover
- Browsers
- Chrome 125+, Firefox 147+, Safari 26+
- JavaScript
- None
Demo
Anatomy
navThe navigation, named witharia-label.button popovertargetThe button that expands the list.ul popoverThe expanded list, above the page and anchored under the button.aA link in the list.
HTML code
<nav aria-label="Main navigation">
<ul>
<li>
<!-- Trigger: opens and closes the submenu -->
<button type="button" popovertarget="account-menu">My account</button>
<!-- Submenu: plain links in a popover, with no menu role -->
<ul id="account-menu" popover>
<li><a href="/account/profile">My profile</a></li>
<li><a href="/account/orders">My orders</a></li>
<li><a href="/account/settings">Settings</a></li>
<li><a href="/sign-out">Sign out</a></li>
</ul>
</li>
<li><a href="/help">Help</a></li>
</ul>
</nav>/* The list anchors under its button, instead of the center of the screen.
One anchor name per button: with a shared name,
every list would open under the last button */
[popovertarget="account-menu"] {
anchor-name: --account-button;
}
#account-menu {
position-anchor: --account-button;
inset: auto;
top: anchor(bottom);
left: anchor(left);
margin: 6px 0 0;
}Usage
Use it for
- Grouping the pages of a section in the main navigation.
- A short list of links, readable at a glance.
Avoid it for
role="menu"androle="menuitem"on a site navigation. They promise the arrow keys of an application menu, like File or Edit.- A list that only opens on hover.
- A "My account" link that also opens the list: an element is a link or a button, never both.
Accessibility
ARIA roles and attributes
A single ARIA attribute, aria-label on the navigation. The button state comes from popovertarget, with no aria-expanded.
| Attribute | Element | Description |
|---|---|---|
aria-label="Main navigation" | nav | Names this navigation landmark: the screen reader tells it apart from the other navigations on the page. |
popovertarget="account-menu" | button | Ties the button to the list id="account-menu". The screen reader gets "My account, collapsed, button", then "expanded" when it opens. |
popover | ul | When closed, the list leaves the accessibility tree. When open, the screen reader gets an ordinary list, placed right after the button in the code: it is read and browsed in order. |
Keyboard navigation
| Key | Action |
|---|---|
| Tab | Reaches the My account button, then the links if the list is open |
| Enter or Space | Opens or closes the list |
| Escape | Closes the list. If focus was on a link, it goes back to the button |
| Tab after the last link | Moves to the Help link. The list stays open until Escape or the next click elsewhere |
Tab order
- The "My account" button.
- "My profile", if the list is open.
- "My orders".
- "Settings".
- "Sign out".
- The "Help" link. With the list closed, Tab goes straight there from the button.
With a screen reader
Example in Chrome with VoiceOver in English. The wording changes from one screen reader to another.
| Action | Announcement |
|---|---|
| Tab to the button | "My account, collapsed, button" |
| Enter | "expanded" |
| Tab | "link, My profile" |
Related RGAA criteria
The RGAA is the French accessibility standard. Its 106 criteria test WCAG 2.1 level AA.
- Criterion 10.7: On each web page, for each element that receives focus, is the focus visible?
- Focus stays visible on the button and on each link.
- Criterion 12.8: On each web page, is the tab order consistent?
- The tab order follows the code order: the button, its links, then the rest.
- Criterion 12.11: On each web page, can additional content that appears on hover, on focus or when a user interface component is activated be reached with the keyboard, where needed?
- The links that appear when the button is activated can be reached with the keyboard.
Other references
WCAG 2.2
EN 301 549
- Accessibility requirements for ICT products and services (V4.1.1, PDF)Clauses 9.1.3.1, 9.2.1.1, 9.2.4.3, 9.2.4.7, 9.4.1.2
APG pattern
Beyond the APG
| New feature | What it adds | Browsers | In the demo |
|---|---|---|---|
popover and popovertarget | Open the list, close it with Escape or a click elsewhere, and give the button its state, collapsed or expanded. | Chrome 116+, Firefox 125+, Safari 17+ | Yes |
CSS anchor positioning (anchor-name, position-anchor) | Places the list under its button, with no JavaScript calculation. | Chrome 125+, Firefox 147+, Safari 26+ | Yes |
interestfor | Opens the list on hover and on focus, with a delay, with no script. | Chrome 149+, Edge 149+ | No |
Variations
Link and button side by side
The "My account" link leads to the account home page, and a button right next to it expands the list. Each keeps a single role.
<li>
<a href="/account">My account</a>
<button
type="button"
popovertarget="account-menu"
aria-label="Account pages">▾</button>
<ul id="account-menu" popover>…</ul>
</li>With details
details and summary instead of popover. It works in older browsers, but Escape does not close it, and the list stays open when you click elsewhere.
<details>
<summary>My account</summary>
<ul>…</ul>
</details>