Read a position
Where a box sits in a row, in pixels from the row’s start.
In CSS, a box stretched from its parent’s left edge to an anchor’s left edge with right: anchor(--target left) is as wide as the gap, and a query container inside it reads the gap as a number. It followed the anchor in the same frame while an animated sibling moved it (Chrome 155, WebKit 26.4 and Firefox 158: 8 of 8 frames); CSS Anchor Positioning 1 lets an anchor moved by a transform lag a few frames.
Example
Result
Markup
<div class="read-a-position">
<i style="--value: 60"></i>
<i style="--value: 140"></i>
<i class="target"></i>
<b>
<span><output></output></span>
</b>
</div>
CSS
@property --result { syntax: '<integer>'; inherits: true; initial-value: 0; }
.read-a-position output::after { counter-reset: result var(--result); content: counter(result); }
.read-a-position { position: relative; display: flex; }
.read-a-position > i { flex: none; width: calc(var(--value) * 1px); }
.read-a-position > .target { anchor-name: --target; }
.read-a-position > b { position: absolute; left: 0; right: anchor(--target left); }
.read-a-position > b > span { display: block; container-type: inline-size; }
.read-a-position > b > span > output { --result: round(100cqw / 1px); }
/* only makes room for the answer */
.read-a-position { min-height: 1lh; }
Limits
- the box absolutely positioned in the row, and the row positioned (
position: relative); the anchor an item of the row: an anchor that is itself absolutely positioned has to come before the box, and Firefox 158 doesn’t follow one that moves - the anchor at or after the row’s start: a box can’t be narrower than 0, so a position before the row reads 0
- no gap between the items: a gap adds to the position read
- the items packed at the row’s start, with no padding there: the box starts at the row’s padding edge (
left: 0), so padding orjustify-contentadds its offset to the read - the query container inside the anchored box, not the box itself: WebKit 26.4 reads 0 when a lone anchored box is the container (measured)
- a whole-number answer: the read rounds to 1px
- each answer under 1,000,000: from a million up, Chrome passes
--resulton as1e+06, whichcounter-resetrejects, so the counter prints 0 - no margins, padding or borders on the items or the query containers: they add to the widths read, and
100cqwreads the content box - no example nested inside another’s row: an anchor name is the whole document’s, so the outer box takes the inner example’s anchor (400 for 200)
- no other registration of
--resulton the page: a later@property --resultthat doesn’t inherit leaves the read right and the counter at 0
Browser support
| Chrome | Safari | Firefox | |
|---|---|---|---|
| Example | 140 | 26 | 158 |
Each row gives the first versions that support every feature its example uses, by MDN’s browser-compat-data. The Example was run in Chrome 155, Safari’s WebKit 26.4 and Firefox 158.