Re: [csswg-drafts] [css-values] Proposal: add sibling-count() and sibling-index() (#4559)

The CSS Working Group just discussed `[css-values] Proposal: add sibling-count() and sibling-index()`, and agreed to the following:

* `RESOLVED: Add sibling-count() and sibling-index() to css-values-5 ED`

<details><summary>The full IRC log of that discussion</summary>
&lt;myles> argyle: hi<br>
&lt;argyle> just got out of a meeting!<br>
&lt;fantasai> scribenick: fantasai<br>
&lt;fantasai> scribenick: myles<br>
&lt;fantasai> scribe+<br>
&lt;fantasai> [bramus explains the proposal]<br>
&lt;bramus> https://gist.github.com/bramus/45878ffc94a7318d63eb83a8882dfcc2<br>
&lt;fantasai> bramus: Right now they use various nasty selectors to achieve this<br>
&lt;fantasai> bramus: it's really not great<br>
&lt;myles_> bramus: somethign that we see authors do a lot is they have the need to have access to the value of n of nth child. They want to know on an element which n am i, and how many siblings are there. This is used for staggared animations, where every sybling has a little delay based on which child it is. Or, placing something around a circle - you need which item you are and how many items there are. Right now authors hack around this using nasty selectors<br>
&lt;myles_> bramus: I'm still proposing why authors need this<br>
&lt;emilio> q<br>
&lt;fantasai> argyle: There's lots of use cases.<br>
&lt;emilio> q+<br>
&lt;fantasai> argyle: Dynamic color distances, dynamic [missed]<br>
&lt;fantasai> argyle: recursion and tying things to position in the tree is fun<br>
&lt;fantasai> argyle: sibling-index() and sibling-counter(), and child-count()<br>
&lt;fantasai> argyle: these are static values that are about the leaf on the branch. They don't change, even if you change to display:none<br>
&lt;fantasai> argyle: but gives many possibilities<br>
&lt;fantasai> argyle: There's nasty selectors that do this, e.g. using :nth-child() with a lot of repetition<br>
&lt;fantasai> argyle: also JS to do it, or template [missed]<br>
&lt;fantasai> argyle: [explains how JS library works on this]<br>
&lt;fantasai> argyle: New one recently proposed was child-count().<br>
&lt;fantasai> argyle: sibling-count() and sibling-index() are directly related to my tree position. Not introducing cycles<br>
&lt;fantasai> argyle: container's child-count() is what you get from JS, CSS doesn't affect it<br>
&lt;fantasai> argyle: but doesn't fulfill every use case, so in some cases need a filtered index<br>
&lt;fantasai> argyle: e.g. if you have 30 items and filtered to 15<br>
&lt;fantasai> argyle: I guess I talked plenty<br>
&lt;TabAtkins> q+<br>
&lt;fantasai> emilio: Offhand this doesn't seem terribly problematic<br>
&lt;Rossen_> ack emilio<br>
&lt;fantasai> emilio: but it's not static<br>
&lt;fantasai> emilio: not worse perf than :nth-child, but you need to invalidate anything that uses these functions whenever a sibling is added or moved<br>
&lt;fantasai> emilio: not to say we shouldn't do it<br>
&lt;fantasai> emilio: I'm a bit inclined to think that child-count() may not be so useful<br>
&lt;fantasai> emilio: problem with child-count() is that you have to go through whole child array to compute it, which is also an issue with nth-child if you use it on every element ....<br>
&lt;fantasai> emilio: needs to be optimized similarly to nth-child<br>
&lt;fantasai> emilio: presumably these would go inside calc()?<br>
&lt;fantasai> argyle: often<br>
&lt;fremy> @ emilio, child-count() is useful if you want to divide a space or time (child-index() / child-count())<br>
&lt;fantasai> emilio: other question would be, right now a lot of things assume numbers are resolved statically<br>
&lt;fantasai> emilio: e.g. at parse time<br>
&lt;fantasai> emilio: so on one hand, feel that this would be easier implementation-wise if we did it like variables<br>
&lt;fantasai> emilio: but matter of implementation complexity<br>
&lt;fantasai> emilio: I think this will take a lot more time if we do it in calc() than if we do it like variables<br>
&lt;Rossen_> q?<br>
&lt;fantasai> emilio: which... is fine.<br>
&lt;fantasai> argyle: Let me show you a demo<br>
&lt;argyle> https://www.irccloud.com/pastebin/EsOxTEIg/<br>
&lt;fantasai> emilio: In variables, if you do like a custom property, then ? works<br>
&lt;argyle> env()<br>
&lt;argyle> yeah<br>
&lt;fantasai> emilio: but then we need to keep things valid at parse time<br>
&lt;fantasai> emilio: if you're using invalid stuff around sibling-index(), would have same error behavior as custom properties<br>
&lt;fantasai> emilio: instead of falling back to previous declaration, you would get invalid-at-computed-value-time<br>
&lt;fantasai> TabAtkins: I think this would be useful for reasons mentioned<br>
&lt;fantasai> TabAtkins: only concern is implementation complexity and performance<br>
&lt;fantasai> TabAtkins: e.g. this defeats style sharing<br>
&lt;fantasai> TabAtkins: Discussing similar problem, dbaron explained the concerns<br>
&lt;fantasai> TabAtkins: I'm not an implementer, can't express those concerns about perf. But there are performance footguns involved here<br>
&lt;Rossen_> ack TabAtkins<br>
&lt;fantasai> emilio: The main perf issue, if you use sibling-count() etc., then every sibling gets its own style<br>
&lt;fremy> q+<br>
&lt;fantasai> emilio: whereas if you do :nth-child(2n), then you can share styles between the things that match that rule<br>
&lt;fantasai> s/count()/index()/<br>
&lt;fantasai> emilio: It's not trivial to optimize it to preserve style sharing<br>
&lt;fantasai> emilio: I guess :has() is worse<br>
&lt;fantasai> TabAtkins: the things people do today, where people do explicit :nth-childs(), is just as bad<br>
&lt;fantasai> TabAtkins: so the question is, would making this more likely to be used because it's easier?<br>
&lt;Rossen_> ack fremy<br>
&lt;fantasai> fremy: a lot of the ? are using this to make the demo work<br>
&lt;fantasai> fremy: she has an inline style on every element that says, e.g. --index: 1; --index: 2; etc.<br>
&lt;fantasai> fremy: what ppl do today is probably worse<br>
&lt;fantasai> emilio: main question is, does this make it too easy to do the wrong thing<br>
&lt;fantasai> emilio: I'm not too concerned about style sharing in particular, more concerned about making it work in calc() or nth kind of thing<br>
&lt;fantasai> emilio: Like attr(). It used to be a strongly-typed thing. Then we switched to more like variables<br>
&lt;argyle> q+<br>
&lt;fantasai> emilio: we ended up deciding that fixing things was hard, so make it work like custom properties<br>
&lt;myles_> fantasai: you can't ever have an invalid output of siblings or sibling index<br>
&lt;fantasai> TabAtkins: We changed attr() because you can have an invalid attribute that won't parse<br>
&lt;fantasai> TabAtkins: having attr() as a length is more complex<br>
&lt;fantasai> emilio: well, it should be invalid for pseudo-elements<br>
&lt;fantasai> emilio: what index would those be?<br>
&lt;fremy> +1; sibling-index() in rgba() sounds like a great reason to make this a variable substitution<br>
&lt;fantasai> emilio: it's not hard, it's a lot of work to fix<br>
&lt;Rossen_> q?<br>
&lt;TabAtkins> nothing weirder about `rgba(sibling-index()...)` vs `rgba(sin(5) ...)`<br>
&lt;fantasai> argyle: I'm curious about concatenation<br>
&lt;Rossen_> ack argyle<br>
&lt;fantasai> argyle: what if I want to create an ident that uses the sibling-index()<br>
&lt;fantasai> argyle: is that invalid? it's not really a string I'm appending<br>
&lt;fantasai> argyle: also follow-up questions about nth-child syntax<br>
&lt;fantasai> argyle: can I filter on a list and then get a sibling index of the filtered index<br>
&lt;fantasai> argyle: to get the index after pre-filtering<br>
&lt;bramus> seems like a follow up issue?<br>
&lt;TabAtkins> fantasai: I can see the use-cases for that<br>
&lt;Rossen_> ack fantasai<br>
&lt;TabAtkins> fantasai: like things with a [hidden], filter them out and use th eindex of what remains<br>
&lt;TabAtkins> fantasai: you can do an :nth-child() selector<br>
&lt;TabAtkins> fantasai: but could do sibling-index(of &lt;selector>)<br>
&lt;argyle> this suffers from naive staggering https://codepen.io/argyleink/pen/VwBKjwj<br>
&lt;TabAtkins> s/you can do/you can't do/<br>
&lt;Rossen_> q?<br>
&lt;argyle> this was one of the most requested features at CSS Day<br>
&lt;TabAtkins> fantasai: I can def see the use-cases, and the perf concerns<br>
&lt;TabAtkins> fantasai: last time we had something with similar profile was :has(), which stayed as a draft for a decade<br>
&lt;bkardell_> More than a decade :)<br>
&lt;TabAtkins> fantasai: So I feel like if we think this is a good idea but have perf problems, maybe we put it in Value 5 ED and note that it has perf problems and we're still deciding if it's good to add or ot<br>
&lt;fantasai> Rossen_: So proposal is to add to work on Values module<br>
&lt;fantasai> argyle: As an author you see :nth-child(), and think, I see you have that number. you know the number. Just give it to me. I want it.<br>
&lt;fantasai> Rossen_: any objections to adopt into Values 5, and then figure out if it's doable?<br>
&lt;fantasai> dbaron: If we put it in a spec, likely to get implemented eventually even if 10-15 years later<br>
&lt;fantasai> bramus: Authors want it. One of the most requested features<br>
&lt;fantasai> bramus: #1 request at CSS Day<br>
&lt;fantasai> bramus: people asked us to make it work<br>
&lt;fantasai> Rossen_: That's a pretty strong signal<br>
&lt;fantasai> POLL: Add sibling-count() and sibling-index() to css-values-5 ED<br>
&lt;fremy> yay, I think it can be made efficient<br>
&lt;SebastianZ> Yay<br>
&lt;argyle> yay<br>
&lt;oriol> +1<br>
&lt;miriam> +1<br>
&lt;astearns> yea<br>
&lt;fantasai> +1<br>
&lt;bramus> yes<br>
&lt;florian> oui<br>
&lt;rachelandrew> yes<br>
&lt;TabAtkins> yes<br>
&lt;changseok> yay<br>
&lt;Rossen_> да<br>
&lt;TabAtkins> (my suggested names were sibling-index(), sibling-count(), child-count(), and tree-depth() )<br>
&lt;ntim_> Yes, but only once we sort out how this works in calc<br>
&lt;hober> i don't think i can vote on this one way or the other without more data<br>
&lt;fantasai> ntim, it just returns a number, right?<br>
&lt;argyle> just a number is all we need<br>
&lt;tantek> +0<br>
&lt;fantasai> RESOLVED: Add sibling-count() and sibling-index() to css-values-5 ED<br>
&lt;ntim_> fantasai: at specified time?<br>
&lt;TabAtkins> yeah it'll just be a &lt;number>, it' susble in calc like any other function that returns a &lt;number><br>
&lt;argyle> thanks y'all, dont have any fun together tonight! 🤣<br>
&lt;fantasai> ntim_, computed value or used value most likely. I haven't read the discussion yet to know which one...<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4559#issuecomment-1642880894 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 19 July 2023 23:11:35 UTC