CSS Anchor Positioning

What You'll Learn

  • How anchor positioning allows elements to position relative to other elements
  • Using anchor-name to define anchor elements
  • Positioning with position-anchor and the anchor() function
  • Creating tooltips, dropdowns, and popovers without JavaScript
  • Understanding position-area for simplified positioning
  • Browser support and fallback strategies for anchor positioning

Introduction to Anchor Positioning

CSS Anchor Positioning is a cutting-edge feature that allows you to position elements relative to other elements (called anchors) purely with CSS. This eliminates the need for JavaScript to calculate positions for tooltips, dropdowns, popovers, context menus, and similar UI patterns.

Before anchor positioning, creating a tooltip required either absolute positioning with manual pixel calculations or JavaScript to dynamically position the tooltip relative to its trigger. Anchor positioning makes this declarative and automatic.

Basic Concept: Anchors and Targets

Anchor positioning involves two elements: the anchor element (the reference point) and the positioned element (the element being positioned). The anchor is given a name using anchor-name, and the positioned element references it with position-anchor.

Syntax

/* Define the anchor element */ .button { anchor-name: --my-button; } /* Position an element relative to the anchor */ .tooltip { position: absolute; position-anchor: --my-button; /* Reference the anchor */ /* Position above the button */ bottom: anchor(top); /* Tooltip bottom = button top */ left: anchor(center); /* Align to horizontal center */ translate: -50% -0.5rem; /* Center and add gap */ }

Example

<button class="button">Hover me</button> <div class="tooltip">I'm a tooltip!</div>

Rendered Result:

The anchor() Function

The anchor() function returns a position value relative to the anchor element's edges or center. You use it within positioning properties like top, bottom, left, and right.

Available Anchor Positions

/* Edge positions */ top: anchor(bottom); /* Position below anchor */ bottom: anchor(top); /* Position above anchor */ left: anchor(right); /* Position to the right of anchor */ right: anchor(left); /* Position to the left of anchor */ /* Center positions */ left: anchor(center); /* Align to horizontal center */ top: anchor(center); /* Align to vertical center */ /* Specific edges */ top: anchor(top); /* Align top edges */ bottom: anchor(bottom); /* Align bottom edges */ left: anchor(left); /* Align left edges */ right: anchor(right); /* Align right edges */

Practical Example: Dropdown Menu

A common use case is positioning a dropdown menu below a button. The menu automatically positions itself relative to the button without any JavaScript calculations.

CSS

.menu-button { anchor-name: --menu-anchor; } .dropdown-menu { position: absolute; position-anchor: --menu-anchor; /* Position below the button */ top: anchor(bottom); left: anchor(left); margin-top: 0.5rem; /* Add some spacing */ /* Initially hidden */ display: none; } .menu-button:hover + .dropdown-menu, .dropdown-menu:hover { display: block; }

HTML

<button class="menu-button">Menu</button> <nav class="dropdown-menu"> <a href="#">Profile</a> <a href="#">Settings</a> <a href="#">Logout</a> </nav>

Rendered Result:

position-area: Simplified Positioning

The position-area property provides a simpler way to position elements around an anchor using keywords instead of the anchor() function. It's available in Chrome 125+.

Syntax

.positioned { position: absolute; position-anchor: --my-anchor; /* Position area: vertical horizontal */ position-area: top center; /* Above, centered */ position-area: bottom left; /* Below, left-aligned */ position-area: right center; /* To the right, centered */ /* Or use logical keywords */ position-area: block-start; /* Above in horizontal writing */ position-area: block-end; /* Below in horizontal writing */ position-area: inline-start; /* Left in LTR, right in RTL */ position-area: inline-end; /* Right in LTR, left in RTL */ }

Example

.popover { position: absolute; position-anchor: --target; position-area: right center; /* To the right, vertically centered */ }

Rendered Result:

anchor-size(): Sizing Based on Anchor

You can also size elements based on the anchor's dimensions using the anchor-size() function. This is useful for creating elements that should match their anchor's width or height.

Syntax

.dropdown { position: absolute; position-anchor: --button; /* Match anchor's width */ width: anchor-size(width); /* Or use height */ height: anchor-size(height); /* Minimum width from anchor */ min-width: anchor-size(width); }

Fallback Positioning with position-try

One of the most powerful features of anchor positioning is automatic fallback positioning. If the positioned element doesn't fit in the preferred location (e.g., a tooltip would go off-screen), it can automatically try alternative positions.

Syntax

/* Define fallback positions */ @position-try --bottom { top: anchor(bottom); left: anchor(center); translate: -50% 0; } @position-try --top { bottom: anchor(top); left: anchor(center); translate: -50% 0; } @position-try --right { top: anchor(center); left: anchor(right); translate: 0 -50%; } .tooltip { position: absolute; position-anchor: --target; /* Try these positions in order until one fits */ position-try-options: --bottom, --top, --right; }

Common Use Cases

1. Tooltips

Position help text above, below, or beside elements without JavaScript.

2. Dropdown Menus

Menu positioning relative to buttons, with automatic fallback if space is limited.

3. Popovers

Content popups anchored to trigger elements.

4. Context Menus

Right-click menus positioned relative to click location.

5. Date Pickers

Calendar overlays positioned below date inputs.

6. Autocomplete Suggestions

Suggestion dropdowns below search boxes.

7. Annotations

Comments or notes anchored to specific document sections.

8. Diagram Labels

Labels positioned relative to diagram elements.

Browser Support and Feature Detection

Anchor positioning is currently only available in Chromium browsers (Chrome 125+, Edge 125+). Always provide fallbacks for browsers that don't support it.

CSS Feature Detection

@supports (anchor-name: --test) { /* Anchor positioning is supported */ .tooltip { position: absolute; position-anchor: --my-anchor; bottom: anchor(top); } } /* Fallback for unsupported browsers */ @supports not (anchor-name: --test) { .tooltip { /* Use traditional positioning */ position: absolute; bottom: 100%; left: 50%; translate: -50% 0; } }

JavaScript Feature Detection

if (CSS.supports('anchor-name', '--test')) { // Anchor positioning is supported console.log('Anchor positioning available'); } else { // Use fallback positioning console.log('Anchor positioning not available'); }

Complete Property Reference

Defining Anchors

/* Name an element as an anchor */ anchor-name: --my-anchor;

Referencing Anchors

/* Reference the anchor */ position-anchor: --my-anchor; /* Position using anchor() function */ top: anchor(bottom); left: anchor(center); bottom: anchor(top); right: anchor(left); /* Or use position-area (simpler) */ position-area: top center; position-area: right; position-area: block-end inline-start;

Sizing from Anchor

width: anchor-size(width); height: anchor-size(height); min-width: anchor-size(width);

Fallback Positioning

/* Define fallback strategies */ @position-try --below { position-area: bottom; } @position-try --above { position-area: top; } /* Use fallbacks */ position-try-options: --below, --above;

Best Practices

1. Always Provide Fallbacks

Since browser support is limited, always include fallback positioning for browsers without anchor positioning support.

2. Use Unique Anchor Names

Anchor names must be unique within the document. Use descriptive, specific names like --profile-menu-anchor rather than generic names like --button.

3. Consider position-try-options

For elements near viewport edges, define fallback positions to ensure they're always visible.

4. Test Across Viewports

Test positioned elements at different viewport sizes and scroll positions to ensure they behave correctly.

5. Be Mindful of Containing Blocks

Anchor positioning works within the same containing block. If elements are in different stacking contexts, positioning may not work as expected.

Limitations and Gotchas

Same Containing Block Required

The anchor and positioned element must share the same containing block for positioning to work. Elements in different positioned ancestors won't work together.

Limited Browser Support

Only Chrome/Edge 125+ support anchor positioning. Firefox and Safari have it in development but it's not yet available in stable releases.

Performance Considerations

While anchor positioning is performant, heavily animated anchored elements may cause layout recalculation. Test performance in real-world scenarios.

Key Takeaways