Weighted sum
The items’ widths, each times its own factor, added up.
In CSS, zoom multiplies a box’s lengths in px by its factor (not auto or a percentage), and the flex row counts the zoomed widths, so the row is as wide as the weighted sum. A query container outside the zoomed boxes reads it.
Example
Result
Markup
<div class="weighted-sum">
<div>
<i style="--value: 60; --f: 2"></i>
<i style="--value: 200; --f: 1"></i>
<i style="--value: 150; --f: 0.5"></i>
</div>
<b><output></output></b>
</div>
CSS
@property --result { syntax: '<integer>'; inherits: true; initial-value: 0; }
.weighted-sum output::after { counter-reset: result var(--result); content: counter(result); }
.weighted-sum { display: inline-grid; width: max-content; grid-template-columns: auto; }
.weighted-sum > div { display: flex; }
.weighted-sum > div > i { flex: none; width: calc(var(--value) * 1px); zoom: var(--f); }
.weighted-sum > b { container-type: inline-size; }
.weighted-sum > b > output { --result: round(100cqw / 1px); }
Limits
- the query container outside the zoomed boxes: inside one,
100cqwreads the width before the zoom (60 for an item 60 wide at zoom 2, read as 120 outside it) - widths of 0 or more and factors above 0:
zoom: 0counts as 1 - with whole-number widths, factors in halves or quarters keep each product exact in all three engines, and eighths in Chrome and WebKit: they round each zoomed length down to 1/64 of a pixel (two thirds of a pixel counts 42/64), Firefox to the nearest 1/60, where an eighth is not exact (Firefox 158: 22 of 80 sums of eighths read 1 off)
- a sum ending in .5 can read 1 low in Chrome, which reads some widths ending in .5 as the number below, 14.5 as 14 (Chrome 155: 11 of the 200 under 400; WebKit and Firefox none)
- no gap between the items, and items that do not flex (
flex: none) - the grid at its natural width (
width: max-content): a grid stretched by its parent, as an item of a grid or of a column flexbox, stretches its auto columns, and the read with them - 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 - each query container stretched across its track (
justify-itemsandjustify-selfat their defaults): aligned to a side or the center, it shrinks to its content, none, and reads 0 - 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.