anchor-name
Lets an element be named so that other elements can be placed relative to it. Replaces dropdown and tooltip positions calculated by JavaScript libraries with CSS declarations.
Modern approach
Give the button a name with anchor-name and set that name in the menu’s position-anchor, and the menu is placed against the button. With position-try-fallbacks, the menu appears above the button when it doesn’t fit below. The browser keeps the position in sync while scrolling.
.menu-button {
anchor-name: --menu-button;
}
.menu {
position: fixed;
position-anchor: --menu-button;
position-area: bottom span-right;
position-try-fallbacks: flip-block;
margin-top: 4px;
}
<div class="dropdown">
<button type="button" class="menu-button">Menu</button>
<div class="menu">
<a href="/settings">Settings</a>
<a href="/logout">Log out</a>
</div>
</div>Legacy approach
A library such as Popper measured the button and calculated the menu’s position. JavaScript recalculated it on every scroll and resize, and placed the menu above the button when it didn’t fit below.
Popper.createPopper(
document.querySelector('.menu-button'),
document.querySelector('.menu'),
{
placement: 'bottom-start',
modifiers: [{ name: 'offset', options: { offset: [0, 4] } }],
},
)
<div class="dropdown">
<button type="button" class="menu-button">Menu</button>
<div class="menu">
<a href="/settings">Settings</a>
<a href="/logout">Log out</a>
</div>
</div>
<script src="https://unpkg.com/@popperjs/core@2"></script>Things to watch when replacing
- With
position: absolute, the menu doesn’t move above the button when page scrolling pushes it past the bottom of the screen. To flip it at the edge of the screen, useposition: fixed. - Once the menu has moved above, it stays there as long as it fits above, even if there is room below again. Unlike Popper, it doesn’t move back as soon as it fits below.
- If several elements share the same name, the last one in source order is used. In repeated components, such as a menu on each item of a list, every menu appears against the last button. Set
anchor-scope: --menu-buttonon the.dropdownthat wraps each component to limit the name to that component (anchor-scopeis supported from Chrome 131). - If the button is hidden with
display: noneor similar, the menu isn’t tied to it.
Related properties and functions
| Property / function | Description |
|---|---|
position-area | Treats the area around the anchor element as a 3×3 grid and sets which cell to place the element in. |
anchor() | Uses the position of an edge of the anchor element as the value of top, left, and so on, for finer control than position-area (e.g. top: anchor(bottom)). |
position-try-fallbacks | Lists the positions to try, in order, when the element doesn’t fit. |
anchor-size() | Uses the anchor element’s width or height as the value of width and similar properties (e.g. matching the menu’s width to the button). |
anchor-scope | Limits how far an anchor name reaches to inside the specified element. |
Fallback
In browsers without support, position-anchor and the related declarations are ignored, and the menu isn’t placed against the button. Branch with @supports and place the menu below the button, using .dropdown as the reference. It won’t flip at the edge of the screen, but the menu is still shown and usable. If an ancestor of .dropdown has overflow: hidden, the menu may be cut off.
@supports not (anchor-name: --a) {
.dropdown {
position: relative;
}
.menu {
position: absolute;
top: 100%;
left: 0;
}
}
If flipping is essential even in browsers without support, use a library such as Floating UI (Popper’s successor).
Browser Support
Chrome
v125+2024-05-14Edge
v125+2024-05-17Safari
v26+2025-09-15Safari (iOS)
v26+2025-09-15Firefox
v147+2026-01-13