Here’s a small but fun use case for CSS Anchor Positioning, using it to keep multiple labels around a progress bar readable, without touching JavaScript.
The goal is simple: we have a horizontal progress bar with three labels: one on the left, one on the right, and one that should follow the progress “tip”. We want that center label to sit as close as possible to the current progress, but never overlap with either side label.
To make things easier, we’ll assume:
- Only the center label needs to move dynamically, the side labels stay at their ends.
- The progress bar is wide enough to fit all three labels with some spacing.
Describing the layout as rules
Instead of hard-coding coordinates, it helps to think in terms of a small set of layout rules the browser can try in order.
For the center label, the logic can be written as:
- Try placing the center label to the left of the progress tip, with a margin.
- If that would overlap something, try placing it to the right of the progress tip, also with a margin.
- If the tip is already too close to another label, place the center label next to that label instead, with a wider margin to keep everything readable.
CSS Anchor Positioning is very good at this style of “try a few positions until one fits” layout. The @position-try at-rules let us declare those strategies explicitly and let the browser pick whichever one does not collide with the container or other constraints.
In this example, I use three named anchors:
--prog-bar: the progress bar itself (specifically, its right edge as the “tip”)--left-label: the fixed label on the left--right-label: the fixed label on the right.
The moving center label is then positioned relative to these anchors.
Defining @position-try strategies
Here are the two position-try rules that implement the logic above:
@position-try --bar-left { position-area: none; right: max( calc(anchor(--prog-bar right) + var(--container-padding)), calc(anchor(--right-label left) + var(--label-gap)) ); margin-left: calc( var(--container-padding) + anchor-size(--left-label width) + var(--label-gap) );}
@position-try --bar-right { position-area: none; left: max( calc(anchor(--prog-bar right) + var(--container-padding)), calc(anchor(--left-label right) + var(--label-gap)) ); margin-right: calc( var(--label-gap) + anchor-size(--right-label width) + var(--container-padding) );}Conceptually:
--bar-leftcorresponds to “try to sit just to the left of the progress tip”.--bar-rightcorresponds to “otherwise, sit just to the right of the progress tip”.
The “third rule” (move next to whichever label is closer) is effectively folded into the max() expressions:
- For
right/leftwe take the maximum of:- the tip position plus container padding, and
- the neighbouring label plus a label gap.
This means:
- If there’s plenty of room, the center label hugs the progress tip.
- If the tip is about to collide with a side label, the center label gets pushed away so that it sits beside that label instead, maintaining at least
var(--label-gap)of space.
Avoiding overlap with anchor-size()
The margins are where the overlap-avoidance really happens.
Take this line as an example:
margin-left: calc( var(--container-padding) + anchor-size(--left-label width) + var(--label-gap));Here we:
- Read the actual width of the left label via
anchor-size(--left-label width). - Add the container’s padding and a label gap.
- Use that as the center label’s margin, so its text always clears the left label by at least that gap.
In other words, instead of guessing spacing with hard-coded numbers, we attach the spacing directly to the real measured size of the anchors. That’s exactly the kind of thing anchor-size() is designed for.
The same idea is used for margin-right with the right label.
Putting it together
Once the @position-try rules are defined, the center label simply opts in to them, for example:
.label.center { position: absolute; top: var(--container-padding); position-try: --bar-left, --bar-right; position-anchor: --prog-bar; position-area: left;}The browser will then:
- Try
--bar-left. - If that would cause an overlap or violate constraints, fall back to
--bar-right.
Combined with the max() insets and anchor-size()-based margins, that’s enough to:
- Keep the center label near the progress tip,
- Prevent it from overlapping either side label,
- Adjust spacing automatically if label text length changes,
- Do all of this with zero JavaScript.
The full implementation – including the anchors and layout container – is in the CodePen embed above.
Browser support
CSS Anchor Positioning is still relatively new, and support is rolling out across browsers. Before using this technique in production, it’s worth checking current support status or adding a progressive enhancement fallback.
You can use the Baseline widget below to see the latest support details for anchor positioning across engines:


Leave a Reply