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
/* 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-element> <anchor-side>, <length-percentage>)
The parameters are:
<anchor-element>
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 itsposition-anchor
property, or associated with the element via theanchor
HTML attribute, is used.Note: Specifying an
<anchor-element>
inside ananchor()
function does not associate an element with an anchor; it only positions the element relative to that anchor. Theposition-anchor
CSS property or theanchor
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 whichanchor()
is set, the fallback value is used. Valid values include:top
-
The top of the anchor element.
right
-
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 introduces two additional
<anchor-side>
values,inside
andoutside
, that 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-element>
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:
top
left
bottom
right
inset
shorthandinset-block-start
inset-block-end
inset-block
shorthandinset-inline-start
inset-inline-end
inset-inline
shorthand
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 butinset-block-end: anchor(left)
is incompatible. Ifinset-block-end: anchor(left, 50px)
were set, the computed value would be50px
, and the positioned element would be positioned50px
from the block end (bottom) of its nearest positioned ancestor or the viewport, depending on theposition
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, butinset-block-end: anchor(top)
is incompatible. Ifinset-block-end: anchor(top, 50px)
were set, the computed value would be50px
, and the positioned element would be positioned50px
from the block end (left or right depending on the writing mode) of its nearest positioned ancestor or the viewport, depending on theposition
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 modesleft 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 modestop 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:
.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:
.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-element>
names 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
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>
that we will position relative to that anchor:
<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.
.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.
<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.
.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.
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.
<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
values, a position
value of absolute
, and different inset values to position the anchors in a rectangle formation.
.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.
.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