CSS Anchor Positioning (Advanced): Position Elements Relative to Anchors
CSS Anchor Positioning lets you place one element relative to another element without using JavaScript for layout math. It is designed for things like tooltips, dropdowns, callouts, and floating labels that need to stay attached to a chosen anchor while the page scrolls or resizes.
Quick answer: Anchor positioning gives a positioned element a relationship to an anchor element, then lets CSS place that element using functions such as anchor() and anchor-size(). It is useful when you want CSS to handle anchored UI placement instead of measuring coordinates in script.
Difficulty: Advanced
You'll understand this better if you know: basic CSS positioning, the box model, and how position, inset, and stacking contexts work.
1. What Is CSS Anchor Positioning?
CSS Anchor Positioning is a set of positioning features that lets a “floating” element align itself to a named anchor element. The anchor can be a button, icon, input, or any other element that serves as the reference point for placement.
- It connects two elements through CSS rather than script.
- It is intended for anchored UI such as popovers, tooltips, menus, and badges.
- It works with normal CSS positioning concepts instead of replacing them.
- It gives you more control over where an element appears around its anchor.
Think of the anchor as the element you point at, and the anchored box as the element that follows that point.
2. Why CSS Anchor Positioning Matters
Before anchor positioning, developers often used JavaScript to measure an element’s rectangle, calculate where another element should go, and update that placement on scroll or resize. That works, but it adds code, event handling, and maintenance.
Anchor positioning matters because it reduces layout glue code and keeps placement rules in CSS, where visual rules usually belong. It is especially useful for interface pieces that must stay near a trigger element while still avoiding collisions with the viewport or nearby content.
It is not a replacement for all layout. It solves a specific problem: positioning one element in relation to another element in a predictable, declarative way.
3. Basic Syntax or Core Idea
Anchor positioning uses two main ideas: declaring an anchor and then consuming that anchor from another element. The exact feature set is still advanced and can vary by browser support, but the core model is straightforward.
Declare an anchor
A reference element can expose an anchor name so other elements can position against it.
button {
anchor-name: --trigger;
}This means the button can act as the target for positioning rules used elsewhere.
Position a related element
The anchored element can refer to that name and use anchored offsets.
.tooltip {
position: absolute;
position-anchor: --trigger;
inset-block-start: anchor(bottom);
inset-inline-start: anchor(left);
}The important idea is that the tooltip does not need hard-coded coordinates. It asks CSS to place it relative to the anchor’s box.
4. Step-by-Step Examples
Example 1: A tooltip below a button
This example places a tooltip underneath its trigger. The tooltip uses the anchor’s bottom edge for vertical placement and left edge for horizontal alignment.
button {
anchor-name: --help-btn;
}
.tooltip {
position: absolute;
position-anchor: --help-btn;
inset-block-start: calc(anchor(bottom) + 8px);
inset-inline-start: anchor(left);
}The tooltip sits just below the button with a small gap. The calc() function adds spacing without needing custom JavaScript measurements.
Example 2: A dropdown aligned to the right edge
Menus often need edge alignment so they line up with their trigger. Here the anchored panel aligns its inline end with the anchor’s inline end.
.menu-button {
anchor-name: --menu;
}
.menu-panel {
position: absolute;
position-anchor: --menu;
inset-block-start: anchor(bottom);
inset-inline-end: anchor(right);
}This pattern is useful when the menu should appear attached to the trigger’s edge rather than centered under it.
Example 3: Centering a popover on the anchor
Sometimes the best placement is centered horizontally over the anchor. You can combine anchor-based values with transforms or offset calculations.
.popover {
position: absolute;
position-anchor: --trigger;
inset-block-start: anchor(bottom);
inset-inline-start: anchor(center);
transform: translateX(-50%);
}The transform shifts the box back by half its own width so the centered anchor point becomes the visual center of the popover.
Example 4: Sizing to the anchor
Anchor positioning is not only about location. The size of the anchor can also be reused so related elements feel visually connected.
.badge {
position: absolute;
position-anchor: --avatar;
inline-size: anchor-size(inline);
block-size: anchor-size(block);
}This is useful when a floating UI should match the trigger’s dimensions or grow in a controlled way based on it.
5. Practical Use Cases
- Tooltips that appear next to a button or icon.
- Dropdowns and menus that should align to a trigger element.
- Context popovers that need to follow a selected chip or tag.
- Inline hints that must stay attached to form fields.
- Floating badges or callouts that should track a card or avatar.
- Guided tours where each step points to a specific UI element.
These are all cases where the placement depends on another element’s position, not on the document flow alone.
6. Common Mistakes
Mistake 1: Forgetting to create the anchor name
Anchor positioning only works when the reference element actually exposes a matching anchor name. If the names do not match, the anchored element has nothing to attach to.
Problem: The tooltip refers to --help-btn, but the button never defines that anchor name, so the browser cannot resolve the position.
button {
/* missing anchor-name */
}
.tooltip {
position-anchor: --help-btn;
inset-block-start: anchor(bottom);
}Fix: Give the anchor element the same name that the floating element references.
button {
anchor-name: --help-btn;
}
.tooltip {
position-anchor: --help-btn;
inset-block-start: anchor(bottom);
}The corrected version works because both sides refer to the same anchor identity.
Mistake 2: Using anchor functions without a positioned element
Anchored placement still depends on normal CSS positioning rules. If the floating box is not positioned, the anchor-based offsets do not behave as expected.
Problem: The element uses anchor() values, but it is still participating in normal flow, so the offsets do not place it like a floating panel.
.tooltip {
position-anchor: --help-btn;
inset-block-start: anchor(bottom);
}Fix: Use a positioned layout mode such as absolute or fixed when the element is meant to float.
.tooltip {
position: absolute;
position-anchor: --help-btn;
inset-block-start: anchor(bottom);
}The corrected version works because the tooltip is now treated as a positioned box that can be anchored.
Mistake 3: Expecting anchor positioning to fix overflow automatically
Anchor positioning helps place an element, but it does not automatically solve every collision problem. A tooltip can still overflow the viewport or be clipped by a container.
Problem: The element is positioned relative to the anchor, but there is no collision handling or fallback placement, so it may render off-screen.
.tooltip {
position: absolute;
position-anchor: --trigger;
inset-block-start: anchor(bottom);
inset-inline-start: anchor(left);
}Fix: Add fallback placement logic and consider viewport-aware sizing or alternative alignment rules.
.tooltip {
position: absolute;
position-anchor: --trigger;
inset-block-start: anchor(bottom);
inset-inline-start: anchor(center);
max-inline-size: min(90vi, 20rem);
}The fixed version is more resilient because it reduces the chance of placing the box outside the visible area.
7. Best Practices
Use anchor names that describe the relationship
Choose names like --menu-trigger or --tooltip-target instead of vague names. Clear names make anchored layouts easier to maintain when a component has multiple floating parts.
.icon-button {
anchor-name: --tooltip-target;
}Descriptive anchor names help you understand what the relationship means without reading the whole stylesheet.
Keep the floating element visually close to the trigger
The feature works best when the anchored element appears to belong to the same interaction. Small offsets and consistent spacing make the UI easier to scan.
.tooltip {
position-anchor: --tooltip-target;
inset-block-start: calc(anchor(bottom) + 0.5rem);
}A small, consistent gap reads as intentional and avoids visual crowding.
Use fallback sizing for constrained viewports
Anchored components can become too wide or too tall for a small screen. Add maximum sizes so they can adapt when space is tight.
.popover {
max-inline-size: min(24rem, 90vi);
overflow: auto;
}This keeps the anchored box usable when the available space is smaller than expected.
8. Limitations and Edge Cases
- Browser support is still evolving, so you should verify behavior in your target browsers before relying on it for critical UI.
- An anchored element can still be clipped by overflow boundaries, transformed ancestors, or stacking contexts.
- Anchor positioning helps with placement, but not every collision or auto-flip scenario is handled automatically.
- It works best for discrete floating UI, not for general page layout or large responsive grids.
- Some fallback techniques may still be necessary for browsers that do not support the feature.
- When an anchor changes size or position during layout, the anchored box may move with it, which is expected but can be surprising if you expected fixed coordinates.
One of the most common “not working” reports is that the box appears in the wrong place because another ancestor creates a clipping or containing context. In those cases, the anchor math may be correct, but the rendering context still prevents the element from being visible where you want it.
9. Practical Mini Project
This mini project shows a help icon with a tooltip that appears below it and stays aligned to the icon. The example is intentionally small but complete so you can see how the pieces fit together.
<div class="help-field">
<button class="help-button" type="button">?
<div class="tooltip">Enter a valid email address.</div>
</div>
.help-field {
position: relative;
padding: 2rem;
}
.help-button {
anchor-name: --help;
inline-size: 2rem;
block-size: 2rem;
}
.tooltip {
position: absolute;
position-anchor: --help;
inset-block-start: calc(anchor(bottom) + 0.5rem);
inset-inline-start: anchor(left);
padding: 0.5rem 0.75rem;
background: #222;
color: #fff;
border-radius: 0.5rem;
}The button becomes the anchor, and the tooltip uses that anchor to stay attached underneath it. In a real app, you would also add visibility rules and fallback behavior for unsupported browsers.
10. Key Points
- Anchor positioning lets one element position itself relative to another element.
- anchor-name defines the reference element, and position-anchor selects it.
- anchor() and anchor-size() let you reuse the anchor’s geometry in CSS.
- It is especially useful for tooltips, menus, popovers, and other floating UI.
- It does not eliminate the need for overflow handling, sizing constraints, or browser support checks.
11. Practice Exercise
Build an anchored info card that appears below a card title and stays aligned with the title when the content above it changes.
- Create a heading element that acts as the anchor.
- Create a floating info panel that positions itself beneath that heading.
- Add a small gap between the heading and the panel.
- Limit the panel width so it remains readable on small screens.
Expected output: A title with a small panel directly beneath it, aligned to the title’s start edge.
Hint: Use anchor-name on the heading and position-anchor plus anchor() on the panel.
Solution:
<section class="card">
<h2 class="card-title">Product details</h2>
<div class="info-panel">
Free shipping on orders over $50.
</div>
</section>
.card {
position: relative;
padding: 2rem;
}
.card-title {
anchor-name: --card-title;
margin: 0;
}
.info-panel {
position: absolute;
position-anchor: --card-title;
inset-block-start: calc(anchor(bottom) + 0.5rem);
inset-inline-start: anchor(left);
max-inline-size: min(20rem, 90vi);
padding: 0.75rem;
background: #f3f4f6;
border: 1px solid #d1d5db;
}This solution keeps the panel tied to the heading without hard-coded pixel coordinates. It is a compact pattern you can adapt to badges, menus, and other anchored surfaces.
12. Final Summary
CSS Anchor Positioning is an advanced layout feature for attaching one element to another element in a declarative way. It is most valuable for floating UI such as tooltips, menus, and popovers, where the anchor should drive the final placement.
The core workflow is simple: define an anchor, point another element at it, and use anchor-based functions to calculate offsets or size. In practice, you still need to think about overflow, clipping, fallback behavior, and browser support.
If you already know CSS positioning well, anchor positioning is a powerful next step for building more resilient interface components with less script. A good next topic is the related set of CSS popover and positioning features that help manage floating interfaces together.