惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
B
Blog
WordPress大学
WordPress大学
Jina AI
Jina AI
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
阮一峰的网络日志
阮一峰的网络日志
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
Google Developers Blog
C
Check Point Blog
月光博客
月光博客
L
LangChain Blog
GbyAI
GbyAI

1A23 Blog

Rotated Background Patterns in CSS with SVG Shift-JIS / UTF-8 文字化け解読:実はもうちょっと読めるかも — 1A23 Blog DAM Karaoke in Round1 Tukwila from the View of a Vocaloid Enjoyer — 1A23 Blog ひとりのボカロファンから見る Round1 Tukwila の DAM カラオケ — 1A23 Blog Reverse engineering an IL2CPP NSO binary: Case study of Mojipittan Encore — 1A23 Blog Use WebVTT without actually using WebVTT: Another way to monitor playback progress of HTML Media Elements — 1A23 Blog Flexible and dynamic flow control of Azure DevOps YAML Pipelines using variables — 1A23 Blog Content-aware Infinite Scroll Loop using JavaScript — 1A23 Blog 『初音ミクの消失合作』セリフ文字起こし — 1A23 Blog
Progress Bar Labels with CSS Anchor Positioning
Eana Hufwe · 2025-11-29 · via 1A23 Blog

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:

  1. Try placing the center label to the left of the progress tip, with a margin.
  2. If that would overlap something, try placing it to the right of the progress tip, also with a margin.
  3. 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-left corresponds to “try to sit just to the left of the progress tip”.
  • --bar-right corresponds 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 / left we 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:

  1. Try --bar-left.
  2. 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, and upvote the feature you want to see become interoperable across major browsers: