position-anchor

DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!

The position-anchor property links an absolutely positioned element to an “anchor” element. This will define the default anchor and is used for the several anchor properties and functions on the “target” element.

In other words, the property positions (or anchors) an element to another element that we set as the property’s value

.target {
  position-anchor: --my-anchor
}

By itself, this example does not do anything other than tell the .target element that it’s positioned (or anchored) to some other element that is represented by a dashed ident called --my-anchor. The problem is that we haven’t actually defined what --my-anchor actually is.

We’ll get to a fully working example after we get some more context about the property, including its syntax and accepted values.

Syntax

position-anchor: auto | <anchor-element>;
  • Initial value: implicit
  • Applies to: Absolutely positioned elements
  • Inherited: No
  • Percentages: N/A
  • Computed value: As specified
  • Canonical order: Per grammar
  • Animation: Discrete

Values

/* Keyword values */
position-anchor: auto;

/* <dashed-ident> examples */
position-anchor: --anchor;
position-anchor: --my-anchor;
position-anchor: --myAnchor;

/* Global values */
position-anchor: inherit;
position-anchor: initial;
position-anchor: revert;
position-anchor: revert-layer;
position-anchor: unset;
  • auto: Links a target element to its implicit anchor. An implicit anchor can be found using the non-standard anchor global attribute or using the Popover API.
  • <dashed-ident>: The name of the desired anchor element. The value is called a “dashed” ident because it must be prefixed with two dashes (–) exactly like we do for CSS custom properties, e.g. –my-anchor.

Basic usage

In the first example, using position-anchor alone won’t have any effect. We’ve told our .target element that it is anchored to some other element we’re calling --my-anchor. But what element is --my-anchor representing? We need that, or else we’re not anchored to anything that actually exists.

The easiest way to define an element as an “anchor” for other elements is to slap the anchor-name property on the element we want to be the anchor.

Say we have two unrelated elements in HTML:

<div class="anchor">My Anchor</div>
<div class="target">My Target</div>

We want the .anchor element to be the anchor, and then position the .target element’s position based on the .anchor element’s position.

.anchor {
  anchor-name: --my-anchor;
}

.target {
  position: absolute; /* or position: fixed; */
  position-anchor: --my-anchor;
}

That’s it! There is now an association between the .anchor and .target elements. When we change the .target element’s position, it will use the .anchor element’s position as its starting basis.

But again, we don’t see much happening in this example. That’s because we haven’t changed the .target element’s position to see that relationship in action. So, let’s turn our attention to two different approaches for updating that element’s position: using the anchor() function along inset properties or using the inset-area property.

Method 1: anchor() function and inset properties

The .target element being absolutely positioned means it can be moved around using inset properties (top, right, bottom, left). It would be ideal to position our .target next to the .anchor, but how can we know where the .anchor is to take advantage of inset properties? The anchor function does exactly that. It takes one side of the anchor and resolves to the <length> of where it is positioned.

Now we can attach one side of the .target to another side of the .anchor.

.target {
  position: absolute;
  position-anchor: --my-anchor;

  top: anchor(bottom);
}

This is basically saying, “Stitch the .target top side to the .anchor element’s bottom edge.” Pictures are worth a thousand words:

Two boxes stacked vertically, the top one labeled anchor and the bottom one labeled target.

The anchor() function takes the default anchor linked to the target element, but we can also directly reference an anchor-name if we’re being more explicit about what we’re anchoring to.

.target {
  position: absolute;

  top: anchor(--my-anchor bottom);
}

…or even reference other anchors that are on the page! For example, we can tell the .target element to anchor itself to the --my-anchor element, but we can still position it based on the position of any other anchor on the page simply by calling that in the anchor() function:

.target {
  position: absolute;
  position-anchor: --my-anchor;

  top: anchor(--my-other-anchor bottom);
}

Method 2: inset-area property

Perhaps an “easier” way to re-position an anchor is using the inset-area property. You can think of an imaginary 3×3 grid surrounding the .anchor element:

Three by three grid with a yellow element in the center tile labeled 'anchor'.

We then position the .target element it is anchored to on the grid by column and row, using:

  • physical values like left, right, top and bottom,
  • logical values that respect the current writing mode, like start and end), and
  • the center shared value.

For example, if we were to span the .target element across two tiles on our imaginary grid, we can use the span- prefix on any value, or even span the .target element across the entire grid using the span-all value.

.target {
  position: absolute;
  position-anchor: --my-anchor;

  inset-area: start center,
  /* or */
  inset-area: bottom left,
  /* or */
  inset-area: span-top right,
}

Demo

Specification

The position-anchor property is defined in the CSS Anchor Positioning Module Level 1 specification, which is currently in Working Draft status at the time of writing. That means a lot can change between now and when the feature becomes a formal Candidate Recommendation for implementation, so be careful about using the property on a live website until the specification is adopted by the W3C and implemented by browsers.

Browser support

Data on support for the css-anchor-positioning feature across the major browsers from caniuse.com

Dealing with legacy browser support

Anchor positioning is a relatively new CSS module that doesn’t have full browser support and may have issues with older versions. Its most common use case will be for better tooltips, so a polyfill for a simple tooltip element can be found below. It checks if anchor positioning is supported and creates an old-school tooltip below our anchor element.

@supports not (position-anchor: --my-anchor) {
  .target {
    display: none;
  }

  .anchor {
    position: relative;
    display: flex;
    justify-content: center;
  }

  .anchor::before {
    content: "My Target";
    position: absolute;
    top: 100%;
  }
}

More information and tutorials