sibling-index()

The sibling-index() css function returns an <integer> for the element's ordinal position among its parent's element children. It's 1-based, like :nth-child(): the first child returns 1, and the last returns the length of Element.children.

Syntax

<sibling-index()> = sibling-index()

It takes no arguments. The value is resolved per element, so a single rule gives every sibling a different <integer>.

The JS analogue

[...el.parentElement.children].indexOf(el) + 1

While JS reads once, CSS re-resolves live.

Uses cases

Math on position. Since it returns an integer (not a string), it composes with calc(), mod(), round():

/* alternating offset without :nth-child(odd) */
.card { translate: calc(mod(sibling-index(), 2) * 20px) 0; }

/* fan-out rotation */
.card { rotate: calc((sibling-index() - 3) * 5deg); }

Paired with sibling-count(). Position relative to total is where it gets expressive, normalizing to a 0→1 ratio lets you interpolate anything across a list:

.item {
  --t: calc((sibling-index() - 1) / (sibling-count() - 1));
  opacity: calc(1 - var(--t) * 0.6);
}

Note that counter() gives a similar result but returns a string, which suits generated content rather than calculation.

You can also use sibling-index() to apply dynamic styles, such as varying background colors based on the element’s index:

.menu-item { background-color: hsl(calc((sibling-index() - 1) * 90), 70%, 60%); }

Review relative colors

Powered by Forestry.md