You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-values] Function to retrieve index of element among siblings, or counter on element as integer #1869
Reacted by Ilya Streltsyn, Roman Komarov, Chiri Vulpes, Eero Pitkänen, Emad Omar, Amelia Bellamy-Royds, btoo, jimmyfrasche, Yaohan Chen, Mike Bremford and 8 more
An integer-returning counter() is definitely one way to address this. We could possibly also go with a more direct sibling-index() function that just returns your index in among your siblings, so you don't have to set up a counter explicitly. I can definitely see some uses for this.
If you want the index of an ancestor element to use in a further descendent, you just need to (a) register a custom property to have a <number> type, and (b) set the property using sibling-index() on that parent element. Then you can use var() on the descendant to fetch the value. (You need to register the prop to get CSS to evaluate the function at the place you originally used it; an unregistered var will just preserve the function itself and resolve it on the descendant instead.)
Reacted by jonjohnjohnson, Gaël Poupard, Chiri Vulpes, Eero Pitkänen, Jordan, Kenrick, Romain Menke, Benjamin Devine, btoo, Yaohan Chen and 3 more
changed the title [-][css-selectors] nth-child produces a local variable[/-][+][css-values] Function to retrieve index of element among siblings, or counter on element[/+]on Oct 27, 2017
changed the title [-][css-values] Function to retrieve index of element among siblings, or counter on element[/-][+][css-values] Function to retrieve index of element among siblings, or counter on element as integer[/+]on Oct 27, 2017
If a specific sibling-index() function is added, I guess it could also accept an argument to be consistent with the of S syntax of :nth-child(). For example, sibling-index(S) would return the (1-based) index of the current element among its inclusive siblings that match the selector list S. The problem is if the element does not match S, then maybe return 0.
This, along with a way to get the number of children in an element, would be really nice for staggered animations.
.parent {
--parent-children-count:children-count();
}
.parent .anim {
/* Stagger from start to end */animation-delay:calc(sibling-index() *100ms);
/* Stagger from end to start */animation-delay:calc((var(--parent-children-count) -sibling-index()) *100ms);
}
(@Nokel81 maybe the above shows that you don't need a special way to get values from the parent)
Reacted by Kenrick, Romain Menke, Benjamin Devine, Christopher Kirk-Nielsen, btoo, Venkateshwar, Diego La Manno Alvarez, Philipp Schardt, Yaohan Chen, Adam Argyle and 8 more
My entire Splitting.js library is based around giving these values as CSS variables. I would love for my library to become obsolete (though that would also require ::nth-letter as well 😄).
animation-delay and transition-delay are the most commonly used, but it also allows for other amazing effects. Here's a large collection of uses people have found for these values in CSS: https://codepen.io/collection/XpROaV/
My thoughts on the syntax would be:
child-count() returns the number of child elements
(akin to ['A','B','C'].length)
sibling-index() returns the element's index in relation to its siblings
(akin to ['A','B','C'].indexOf('B'))
sibling-count() returns the total count of adjacent elements
(the parent's child-count() - 1 )
Using sibling-count() you can then calculate a 0-1 range of the element's "position" in the parent. For example:
.children {
animation: fade-in 1s linear;
/* Stagger in all children over the course of 1s */
animation-delay: calc( 1s * ( sibling-index() / sibling-count() ) );
}
Activity
tabatkins commentedon Oct 13, 2017
What would happen in:
?
Nokel81 commentedon Oct 13, 2017
The second one would overwrite the first value. A way around this would be to allow other letters besides n
Loirooriol commentedon Oct 14, 2017
I think allowing
counter()to return an integer would be a better way to address this kind of problems.Nokel81 commentedon Oct 14, 2017
Having not known of counters before this, that is cool. Now, yes I believe that that is a much better way of addressing this problem
tabatkins commentedon Oct 27, 2017
An integer-returning
counter()is definitely one way to address this. We could possibly also go with a more directsibling-index()function that just returns your index in among your siblings, so you don't have to set up a counter explicitly. I can definitely see some uses for this.If you want the index of an ancestor element to use in a further descendent, you just need to (a) register a custom property to have a
<number>type, and (b) set the property usingsibling-index()on that parent element. Then you can usevar()on the descendant to fetch the value. (You need to register the prop to get CSS to evaluate the function at the place you originally used it; an unregistered var will just preserve the function itself and resolve it on the descendant instead.)[-][css-selectors] nth-child produces a local variable[/-][+][css-values] Function to retrieve index of element among siblings, or counter on element[/+][-][css-values] Function to retrieve index of element among siblings, or counter on element[/-][+][css-values] Function to retrieve index of element among siblings, or counter on element as integer[/+]Loirooriol commentedon Oct 27, 2017
If a specific
sibling-index()function is added, I guess it could also accept an argument to be consistent with theof Ssyntax of:nth-child(). For example,sibling-index(S)would return the (1-based) index of the current element among its inclusive siblings that match the selector list S. The problem is if the element does not match S, then maybe return 0.Nokel81 commentedon Oct 28, 2017
The idea of a selector as well is cool but another way to get the parent's sibling count would be
sibling-index(1p)for the first parentjakearchibald commentedon Nov 3, 2019
This, along with a way to get the number of children in an element, would be really nice for staggered animations.
(@Nokel81 maybe the above shows that you don't need a special way to get values from the parent)
shshaw commentedon Dec 4, 2019
My entire Splitting.js library is based around giving these values as CSS variables. I would love for my library to become obsolete (though that would also require
::nth-letteras well 😄).animation-delayandtransition-delayare the most commonly used, but it also allows for other amazing effects. Here's a large collection of uses people have found for these values in CSS: https://codepen.io/collection/XpROaV/My thoughts on the syntax would be:
child-count()returns the number of child elements(akin to
['A','B','C'].length)sibling-index()returns the element's index in relation to its siblings(akin to
['A','B','C'].indexOf('B'))sibling-count()returns the total count of adjacent elements(the parent's
child-count() - 1)Using
sibling-count()you can then calculate a 0-1 range of the element's "position" in the parent. For example:Demo using CSS variables
You can also calculate "distance" from the end (as @jakearchibald showed), or even calculate from the center (example using CSS Variables]
jakearchibald commentedon Jul 20, 2023
It seems like the newer issue, #4559, has more traction. Maybe this should close?
tabatkins commentedon Jul 22, 2023
Yeah, since #4559 is the version that actually got a WG resolution, I'll close this one.