anchor()

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The anchor() CSS function can be used within an anchor-positioned element's inset property values, returning a length value relative to the position of the edges of its associated anchor element.

Syntax

css
/* side or percentage */
top: anchor(bottom);
top: anchor(50%);
top: calc(anchor(bottom) + 10px)
inset-block-end: anchor(start);

/* side of named anchor */
top: anchor(--myAnchor bottom);
inset-block-end: anchor(--myAnchor start);

/* side of named anchor with fallback */
top: anchor(--myAnchor bottom, 50%);
inset-block-end: anchor(--myAnchor start, 200px);
left: calc(anchor(--myAnchor right, 0%) + 10px);

Parameters

The anchor() function's syntax is as follows:

anchor(<anchor-name> <anchor-side>, <length-percentage>)

The parameters are:

<anchor-name> Optional

The anchor-name property value of an anchor element you want to position the element's side relative to. This is a <dashed-ident> value. If omitted, the element's default anchor, referenced in its position-anchor property, or associated with the element via the anchor HTML attribute, is used.

Note: Specifying an <anchor-name> inside an anchor() function does not associate an element with an anchor; it only positions the element relative to that anchor. The position-anchor CSS property or the anchor HTML attribute is still needed to create the association.

<anchor-side>

Specifies the side of the anchor, or the relative distance from the start side, which the element is positioned relative to. If a physical or logical value is used that is not compatible with the inset property on which anchor() is set, the fallback value is used. Valid values include:

top

The top of the anchor element.

The right of the anchor element.

bottom

The bottom of the anchor element.

left

The left of the anchor element

start

The logical start of the anchor element's containing block along the axis of the inset property on which the anchor() function is set.

end

The logical end of the anchor element's containing block along the axis of the inset property on which the anchor() function is set.

self-start

The logical start of the anchor element's content along the axis of the inset property on which the anchor() function is set.

self-end

The logical end of the anchor element's content along the axis of the inset property on which the anchor() function is set.

center

The center of the axis of the inset property on which the anchor() function is set.

<percentage>

Specifies the distance, as a percentage, from the start of the element's content along the axis of the inset property on which the anchor() function is set.

The CSS anchor positioning module specifies two additional <anchor-side> values, inside and outside, which have not yet been implemented.

<length-percentage> Optional

Specifies a fallback value the function should resolve to if the anchor() function would otherwise not be valid.

Return value

Returns a <length> value.

Description

The anchor() function enables positioning an element relative to the edges of an anchor element. It is only valid within inset property values set on absolute or fixed position elements.

It returns a <length> value specifying the distance between the anchor-positioned element side specified by the inset value, and the side of the anchor element specified by the chosen <anchor-side> value. As it returns a <length>, it can be used within other CSS functions that accept length values, including calc(), clamp(), etc.

If no anchor with the name specified by the <anchor-name> exists, or if the positioned element does not have an anchor associated with it (i.e. via the position-anchor property), the first parameter is considered invalid and the fallback <length-percentage> value is used if one is available. For example, if top: anchor(bottom, 50px) were specified on the positioned element but no anchor was associated with it, the fallback value would be used, so top would get a computed value of 50px.

For detailed information on anchor features and usage, see the CSS anchor positioning module landing page and the Using CSS anchor positioning guide.

Properties that accept anchor() function values

The CSS inset properties that accept an anchor() function as a value component include:

Compatibility of inset properties and <anchor-side> values

When using an anchor() function inside an inset property value, the <anchor-side> parameter specified inside the anchor() function has to be compatible with the axis on which the inset property resides.

This means that physical <anchor-side> values can be used within the values of physical inset properties if the property has the same axis direction as the <anchor-side>. In other words, the top and bottom sides are not valid within the left and right property values, and the left and right sides are not valid within top and bottom property values. For example, top: anchor(bottom) is fine, as they are both vertical values but top: anchor(left) is not valid, as left is a horizontal value. If top: anchor(left, 50px) were specified, the fallback value would be used, so top would get a computed value of 50px. If no fallback is present, the inset property behaves as if it were set to auto.

You can use logical <anchor-side> values within both logical and physical inset properties as logical <anchor-side> values are relative to the inset property's relevant axis, whether the property is logical or relative. For example, top: anchor(start), top: anchor(self-end), inset-block-start: anchor(end) and inset-inline-end: anchor(self-start) all work fine.

The story gets more complicated when using physical <anchor-side> parameters within logical inset property values as the physical side has to match the axis the inset property is relevant to within the current writing mode. For example:

  • In a horizontal writing mode, the block direction is top-to-bottom, therefore inset-block-end: anchor(bottom) will work but inset-block-end: anchor(left) is incompatible. If inset-block-end: anchor(left, 50px) were set, the computed value would be 50px, and the positioned element would be positioned 50px from the block end (bottom) of its nearest positioned ancestor or the viewport, depending on the position value set.
  • In a vertical writing mode, the block direction is right-to-left or left-to-right, therefore inset-block-end: anchor(left) will work, but inset-block-end: anchor(top) is incompatible. If inset-block-end: anchor(top, 50px) were set, the computed value would be 50px, and the positioned element would be positioned 50px from the block end (left or right depending on the writing mode) of its nearest positioned ancestor or the viewport, depending on the position value set.

To mitigate the potential for confusion with these values, you are advised to use logical inset properties with logical <anchor-side> values, and physical inset properties with physical <anchor-side> values. You should favor the use of logical values whenever possible because they are better for internationalization.

The center and <percentage> values are valid within the anchor() function within all logical and physical inset properties.

The below table lists the inset properties, and the <anchor-side> parameter values that are compatible with them. We have only listed the longhand inset properties; these comprise the shorthand inset property values.

Inset property Compatible <anchor-side> value
All center
All <percentage>
top and bottom top, bottom, start, end, self-start, self-end
left and right left, right, start, end, self-start, self-end
inset-block-start and inset-block-end start, end, self-start, and self-end
top and bottom in horizontal writing modes
left and right in vertical writing modes
inset-inline-start and inset-inline-end start, end, self-start, and self-end
left and right in horizontal writing modes
top and bottom in vertical writing modes

Using anchor() inside calc()

When the anchor() function refers to a side of the default anchor, you can include a margin to create spacing between the edges of the anchor and positioned element as needed. Alternatively, you can include the anchor() function within a calc() function to add spacing.

This example positions the right edge of the positioned element flush to the anchor element's left edge then adds margin to make some space between the edges:

css
.positionedElement {
  right: anchor(left);
  margin-left: 10px;
}

This example positions the positioned element's logical block end edge 10px from the anchor element's logical block start edge:

css
.positionedElement {
  inset-block-end: calc(anchor(start) + 10px);
}

Positioning an element relative to multiple anchors

You can position an element relative to multiple anchors by specifying different <anchor-name> values inside the anchor() function of different inset properties on the same element (see Element positioned relative to multiple anchors below). This can be used to create useful functionality such as drag handles at the corners of a positioned element that can be used to resize it.

While a positioned element can be positioned relative to more than one anchor element, it is only ever associated with the single anchor defined via its position-anchor property (or the anchor HTML attribute). This is the anchor the element will scroll with when the page scrolls; it can also be used to control when the element is conditionally hidden.

Formal syntax

<anchor()> = 
anchor( <anchor-name>? &&
<anchor-side> , <length-percentage>? )

<anchor-name> =
<dashed-ident>

<anchor-side> =
inside |
outside |
top |
left |
right |
bottom |
start |
end |
self-start |
self-end |
<percentage> |
center

<length-percentage> =
<length> |
<percentage>

Examples

Common usage

In this example, the anchor() function is used to set the height of an anchor-positioned element to the height of its anchor by setting the bottom and top edges to the bottom and top edges of the anchor. The anchor() function within a calc() function is then used to offset the anchor-positioned element from its anchor.

HTML

We include a <div> element, which we'll set as our anchor, and a <p> element that we will position relative to that anchor:

html
<div class="anchor">⚓︎</div>

<p class="positionedElement">This is a positioned element.</p>

CSS

We set the anchor element's anchor-name value as the value of the positioned element's position-anchor property to associate the elements, then set three inset properties on the anchor-positioned element. The first two position the element's top edge flush with the top edge of the anchor and the bottom edge flush with the bottom edge of the anchor. In the third inset property, the anchor() function is used within a calc() function to position the element's left edge 10px to the right edge of the anchor.

css
.anchor {
  anchor-name: --infobox;
  background: palegoldenrod;
  font-size: 3em;
  width: fit-content;
  border: 1px solid goldenrod;
}

.positionedElement {
  position: absolute;
  position-anchor: --infobox;
  margin: 0;
  top: anchor(top);
  left: calc(anchor(right) + 10px);
  bottom: anchor(bottom);
  background-color: olive;
  border: 1px solid darkolivegreen;
}

Results

Comparison of different anchor-side values

This example shows an element positioned relative to an anchor via its top and left properties, which are defined using anchor() functions. It also includes two drop-down menus that allow you to vary the <anchor-side> values inside those anchor() functions, so you can see what effect they have.

HTML

We specify two <div> elements, one with a class of anchor and one with a class of infobox. These are intended to be the anchor element and the positioned element we will associate with it, respectively.

We also include some filler text around the two <div> elements to make the <body> taller so that it will scroll. This example also includes two <select> elements to create the drop-down menus enabling the selection of different <anchor-side> values to place the positioned element with. We've hidden the filler text and the <select> elements for brevity.

html
<div class="anchor">⚓︎</div>

<div class="infobox">
  <p>This is an information box.</p>
</div>

CSS

We declare the anchor <div> as an anchor element by setting an anchor name on it via the anchor-name property. We then associate it with the positioned element by setting the same value for its position-anchor property. top: anchor(--myAnchor bottom) positions the infobox's top edge flush to the bottom edge of its anchor, while left: anchor(right) positions the infobox's left edge flush to the right edge of its anchor. This provides an initial position that will be overwritten when different values are selected from the drop-down menus.

css
.anchor {
  anchor-name: --myAnchor;
}

.infobox {
  position: fixed;
  position-anchor: --myAnchor;
  top: anchor(--myAnchor bottom);
  left: anchor(right);
}

JavaScript

We listen for the change event that occurs when a new <anchor-side> value is selected, and set the selected value as the <anchor-side> in the anchor() function within the infobox's relevant inset property (top or left) value.

js
const infobox = document.querySelector(".infobox");
const topSelect = document.querySelector("#top-anchor-side");
const leftSelect = document.querySelector("#left-anchor-side");

topSelect.addEventListener("change", (e) => {
  const anchorSide = e.target.value;
  infobox.style.top = `anchor(--myAnchor ${anchorSide})`;
});

leftSelect.addEventListener("change", (e) => {
  const anchorSide = e.target.value;
  infobox.style.left = `anchor(${anchorSide})`;
});

Result

Select different values from the drop-down menus to see how they affect the positioning of the infobox.

Element positioned relative to multiple anchors

This example positions an element relative to two different anchors, which are used to set the position of the top-left and bottom-right corners of the anchor-positioned element. The anchors can be moved via keyboard controls or dragged, resizing the positioned element.

HTML

We specify three <div> elements in total. The first two have a class of anchor and will be defined as anchors; each one has an individual id that will be used to provide them with different positioning information. The last <div> has a class of infobox and will be defined as the positioned element. We include the tabindex attribute to enable them to receive keyboard focus.

html
<div id="anchor1" class="anchor" tabindex="0">⚓︎1</div>

<div id="anchor2" class="anchor" tabindex="0">⚓︎2</div>

<div class="infobox">
  <p>This is an information box.</p>
</div>

CSS

The anchors are each given a different anchor-name value, a position value of absolute, and different inset values to position the anchors in a rectangle formation.

css
.anchor {
  position: absolute;
}

#anchor1 {
  anchor-name: --myAnchor1;
  top: 50px;
  left: 100px;
}

#anchor2 {
  anchor-name: --myAnchor2;
  top: 200px;
  left: 350px;
}

The anchor-positioned element, with its position set to fixed, is associated with one anchor via its position-anchor property. It is positioned relative to two anchors by including two different <anchor-name> values with the anchor() functions set on its inset properties. In this case, we used <percentage> values for the <anchor-side> parameter, specifying the distance from the start of the axis of the inset property on which the function is set.

css
.infobox {
  position-anchor: --myAnchor1;
  position: fixed;
  top: anchor(--myAnchor1 100%);
  left: anchor(--myAnchor1 100%);
  bottom: anchor(--myAnchor2 0%);
  right: anchor(--myAnchor2 0%);
}

Result

The positioned element is positioned relative to both anchor elements. Drag them with the mouse or tab to them and use the W, A, S, and D keys to move them up, down, left, and right. See how this changes their position, and as a consequence, the area of the positioned element. Scroll to see how the positions of all the elements are maintained.

Note: This example is a proof-of-concept and not intended to be used in production code. Among its shortcomings, the example breaks if you try to move the anchors past each other horizontally or vertically.

Specifications

Specification
CSS Anchor Positioning
# anchor-pos

Browser compatibility

BCD tables only load in the browser

See also