rank()

Each number’s place in the list sorted smallest first, from 0.

In CSS, order lines the items up smallest first, each 1px wide; a box from the row’s start to an item’s left edge, set by anchor(), is as wide as the items before it: the item’s rank, from 0.

Example

Result
Markup
<div class="rank">
  <i style="--value: 1; anchor-name: --r1"></i>
  <i style="--value: 2; anchor-name: --r2"></i>
  <i style="--value: 3; anchor-name: --r3"></i>
  <b style="right: anchor(--r1 left)">
    <span><output></output></span>
  </b>
  <b style="right: anchor(--r2 left)">
    <span><output></output></span>
  </b>
  <b style="right: anchor(--r3 left)">
    <span><output></output></span>
  </b>
</div>
CSS
@property --result { syntax: '<integer>'; inherits: true; initial-value: 0; }
.rank output::after { counter-reset: result var(--result); content: counter(result); }
.rank { position: relative; display: flex; }
.rank > i { flex: none; width: 1px; order: var(--value); }
.rank > b { position: absolute; left: 0; }
.rank > b > span { display: block; container-type: inline-size; }
.rank > b > span > output { --result: round(100cqw / 1px); }
/* only places the three answers, one a line */
.rank { padding-bottom: 3lh; }
.rank > b:nth-of-type(2) { top: 1lh; }
.rank > b:nth-of-type(3) { top: 2lh; }

Limits

d3.rank gives equal values the same rank; with order, equal keys keep their order in the markup, so each gets its own.

  • whole-number values: calc() rounds a fraction to the nearest whole number, so 1.4 ties with 1 and keeps its place in the markup
  • values from −8,388,608 to 8,388,608 in Firefox 158, which computes a larger calc() in order to a nearby even number (8,388,609 ranks as 8,388,608 there); from −2,147,483,647 to 2,147,483,647 in Chrome 155 and WebKit 26.4
  • items 1px wide that do not shrink (flex: none), with no gap or margins
  • 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 or justify-content adds its offset to the read
  • one anchor name per item, and one box per item that names it: a name shared by several items resolves to the last of them (CSS Anchor Positioning 1 §2)
  • 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)
  • smallest first, as d3.rank’s default; order: calc(-1 * var(--value)) ranks largest first, as d3.rank(…, d3.descending)
  • no padding or borders on the query container: 100cqw reads its 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 --result on the page: a later @property --result that doesn’t inherit leaves the read right and the counter at 0

Browser support

ChromeSafariFirefox
Example14026158

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.