Multiple Anchors | CSS-Tricks


Only Chris, right? You’ll want to view this in a Chromium browser:

This is exactly the sort of thing I love, not for its practicality (cuz it ain’t), but for how it illustrates a concept. Generally, tutorials and demos try to follow the “rules” — whatever those may be — yet breaking them helps you understand how a certain thing works. This is one of those.

The concept is pretty straightforward: one target element can be attached to multiple anchors on the page.



We’ve gotta register the anchors and attach the .target to them:

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

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

.target {
  
}

Wait, wait! I didn’t attach the .target to the anchors. That’s because we have two ways to do it. One is using the position-anchor property.

.target {
  position-anchor: --anchor-1;
}

That establishes a target-anchor relationship between the two elements. But it only accepts a single anchor value. Hmm. We need more than that. That’s what the anchor() function can do. Well, it doesn’t take multiple values, but we can declare it multiple times on different inset properties, each referencing a different anchor.

.target {
  top: anchor(--anchor-1, bottom);
}

The second piece of anchor()‘s function is the anchor edge we’re positioned to and it’s gotta be some sort of physical or logical insettop, bottom, start, end, inside, outside, etc. — or percentage. We’re bascially saying, “Take that .target and slap it’s top edge against --anchor-1‘s bottom edge.

That also works for other inset properties:

.target {
  top: anchor(--anchor-1 bottom);
  left: anchor(--anchor-1 right);
  bottom: anchor(--anchor-2 top);
  right: anchor(--anchor-2 left);
}

Notice how both anchors are declared on different properties by way of anchor(). That’s rad. But we aren’t actually anchored yet because the .target is just like any other element that participates in the normal document flow. We have to yank it out with absolute positioning for the inset properties to take hold.

.target {
  position: absolute;

  top: anchor(--anchor-1 bottom);
  left: anchor(--anchor-1 right);
  bottom: anchor(--anchor-2 top);
  right: anchor(--anchor-2 left);
}

In his demo, Chris cleverly attaches the .target to two