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, use position: 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-button on the .dropdown that wraps each component to limit the name to that component (anchor-scope is supported from Chrome 131).
  • If the button is hidden with display: none or similar, the menu isn’t tied to it.
Property / functionDescription
position-areaTreats 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-fallbacksLists 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-scopeLimits 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-14
  • Edge

    v125+
    2024-05-17
  • Safari

    v26+
    2025-09-15
  • Safari (iOS)

    v26+
    2025-09-15
  • Firefox

    v147+
    2026-01-13

Search by feature name or code

e.g. aspect-ratio, :has(), padding-top

Try a different word or a property name.

Could not load search.