- From: Dael Jackson <daelcss@gmail.com>
- Date: Sun, 10 Sep 2023 11:23:38 -0400
- To: www-style@w3.org
========================================= These are the official CSSWG minutes. Unless you're correcting the minutes, Please respond by starting a new thread with an appropriate subject line. ========================================= Selectors --------- - RESOLVED: Preserve invalid selectors inside forgiving selector lists (such as :is() and :where()) regardless of whether there's an & in them (Issue #8356: Consider preserving invalid selectors in :is() and :where()) CSS Syntax ---------- - RESOLVED: Work on the problem of expressing ranges of children in selectors in a more intuitive way (Issue #4140: Make it easier to express ranges for <An+B> selectors) - There wasn't agreement on what the syntax should be to express ranges of children in selectors so discussion will continue during breaks at the F2F and this will be added back to the agenda when a proposal develops. CSS Values ---------- - RESOLVED: Add sibling-count() and sibling-index() to css-values-5 ED (Issue #4559: Proposal: add sibling-count() and sibling-index()) ===== FULL MEETING MINUTES ====== Agenda: https://github.com/w3c/csswg-drafts/projects/38 Scribe: dbaron Selectors ========= Consider preserving invalid selectors in :is() and :where() ----------------------------------------------------------- github-bot: https://github.com/w3c/csswg-drafts/issues/8356 emilio: For nesting, when you have an & in a nested selector, we resolved to preserve the invalid selector inside so that you could properly track whether there was an &. Makes sense. But inconsistent, in the sense that it's a weird special case. Would be more consistent IMO to preserve all invalid selectors. That way you don't special case nesting. It's also more consistent with @supports and @media, with <general-enclosed>. emilio: ...It feels more generally consistent. I don't think it matters particularly... I don't expect compat issues. The question is... as Oriol mentioned, this also makes the empty selector kind of silly. TabAtkins: As a selectors editor, I agree, would be good to keep it ??? defined. TabAtkins: not sure why we decided to drop the invalid selector arguments in :is() emilio: Implementation-wise, it's easier to just drop it, but if we need to preserve it, easier to preserve always rather than sometimes. emilio: So if nobody objects I think this would be better than the current specified behavior. <bramus> +1 ntim: Isn't there something about forgiving parsing? emilio: That's the behavior of dropping invalid selector. TabAtkins: Nesting cares about whether there's an & at all, so you don't have a newer/older browser behavior switch. dbaron: So you would still be treating invalid selectors the same dbaron: just preserving them in the OM. TabAtkins: Yes emilio: Proposed resolution: preserve invalid selectors inside :is() and :where() regardless of whether there's an & token. matthieudubet: Do for all forgiving selector lists? TabAtkins: I think that's all of them for now, but we should say for all forgiving selector lists. RESOLVED: preserve invalid selectors inside forgiving selector lists (such as :is() and :where()) regardless of whether there's an & in them CSS Syntax ========== Make it easier to express ranges for <An+B> selectors ----------------------------------------------------- github: https://github.com/w3c/csswg-drafts/issues/4140 SebastianZ: I previously suggested a new syntax for expressing An+B selectors in :nth-child() etc. SebastianZ: We were discussing this, we had 2 proposals. They seem orthogonal; we could have both. But I think one I suggested initially is targeting the most common use cases. SebastianZ: Tab was also mentioning some things. SebastianZ: reusing the range syntax from Media Queries, with one addition: adding a "last" keyword to count from the last element instead of the first. TabAtkins: The problem we're trying to solve is that right now a selector targeting a range of elements (e.g., 3rd through 7th), it's possible to write using two :nth-child()s, but it's not obvious how, and tricky. TabAtkins: So the first thing we should agree on is whether to agree on developing a syntax to enable expressing ranges more easily. TabAtkins: And if so we have some suggestions to go over and possibly decide between. TabAtkins: I think it's a reasonably common case (e.g., "select the first 3 elements") TabAtkins: you have to write :nth-child(3-n) or :nth-child(-n+3). I'd prefer n <= 3, like you'd write elsewhere. <SebastianZ> See also https://github.com/w3c/csswg-drafts/issues/4140#issuecomment-517857973 TabAtkins: Do we think this is worth adding to selectors? florian: Yes <miriam> +1 <oriol> +1 fantasai: not sold on the syntax, but seems reasonable to come up with something <fremy> I have written code that would have benefited from this, so sympathetic <dbaron> +1 to working on the problem RESOLVED: Work on the problem of expressing ranges of children in selectors in a more intuitive way. TabAtkins: a few suggestions for syntax. TabAtkins: oriol suggested a different approach from what TabAtkins and SebastianZ are thinking about. TabAtkins: If you're expressing a range, do you want a range on the "n' variable or a range on the output? TabAtkins: You want a range on the output rather than the input. TabAtkins: If your range was 2n and your range is 1-5, are you selecting 2,4,6,8,10 or 2,4 ? TabAtkins: In this case you want 2,4 <TabAtkins> 2n <= 5, for example, will return 2,4 <TabAtkins> if a "<= 5" condition can return 6,8,10 I think that's super weird <astearns> range-limited output? TabAtkins: This ties in to what syntax we're using TabAtkins: I think if you see 2n <= 5, you expect all the values of 2n that result in a value <= 5. emilio: Before anything else, can we agree on making it part of :nth-child() rather than inventing new pseudo-classes. I think it makes sense as part of :nth-child(). TabAtkins: I think basically building this into An+B is good. oriol: I prefer my proposal -- when I started ??? with the An+B syntax, I first assumed that "n" would be strictly positive, then I thought all integers -- there's an implicit condition that "n" is nonnegative. I think this implicit condition may be confusing. I was thinking my proposal adding an explicit condition to n could make things more clear. oriol: That said, it may be true that the other proposal maybe covers more frequent cases in a shorter way. oriol: You can convert from the other proposal to mine by adding another :nth-child() pseudo-class. I'm not opposed to the other one. oriol: I think this is a good point that my proposal covers. <TabAtkins> my actual proposed syntax kinda splits the difference tho, I suppose: ranges must be simple, just a number and n. So `:nth-child(n <= 5)` only, not `2n <= 5`. If you want to both, `:nth-child(n <= 5):nth-child(2n)` or `:nth-child(n <= 5 of 2n)` myles: I think we've been reinventing list comprehensions that are in many proper programming languages. We should take something that already exists. TabAtkins: This is reinventing the range operators that some operators... different syntax space from list comprehensions. myles: I'm not saying to dump python's list comprehensions in CSS -- but I'm saying for input vs. output do what the programming languages do. TabAtkins: I disagree with that on principle -- it's more like a range than a list comprehension. TabAtkins: the syntax affects whether your ranges are on the input on the output. TabAtkins: Different languages make map-then-filter or filter-then-map easier, and I don't think there's a clear reason to prefer one based on precedent. TabAtkins: My preferred syntax proposal makes this moot. Rather than full An+B combined with ranges is that when we do ranges, you're limited to N on one side, a number on one side , and a sign in the middle. IF you want An+b stuff as well, you can do the same ?? as if you're combining 2 conditions together. Not ??? An ???. I proposed we only allow n <= 5. You can decide whether you allow the first 5 children that are also TabAtkins: even or the first five even children, depending on how you write it. hober: If I understand, I think I agree. <TabAtkins> `:nth-child(n <= 5):nth-child(2n)` or `:nth-child(n <= 5 of 2n)` TabAtkins: We can rely on existing CSS facilities. <hober> the case I care about, I think, is something like "give me some things that match this selector, but give me at most N of them." <fantasai> that's :nth-child(An+B of <selector>) fremy: I think we're not going to have consensus today. But I want say I agree with following other languages. I think we should have multiple filters, applied in order author wrote them. I find it hard to understand "2n+3 < 5", no idea what it selects. I think we need something more clear. <ntim> +1 to fremy <TabAtkins> okay so that's `:nth-child(n <= 5 of 2n)`, exactly the same as `:nth-child(n <= 5 of .foo)` if you cared about foo-ness rather than even-ness fremy: :nth-child(2n) is for the even things, and then say first three. fremy: I think this reads better than the mathematic formula. fremy: I think 2n+1<5 is too difficult to understand. <ntim> I agree 2n+5 < 5 is hard to understand <TabAtkins> dangit, sorry, I meant of course `:nth-child(n <= 5 of :nth-child(2n))` SebastianZ: I want to note first proposed syntax also involves "last" keyword as said in beginning, which allows counting from the end. From 3rd element to 3rd-last element, style everything. Wouldn't be possible with second proposed syntax. TabAtkins: We could have negative indexes mean what they do in most programming languages. fantasai: But we don't do that now <fantasai> Like, I really love negative indexes representing from the end. But we don't do that now, and so I think it would be confusing to have it work for some things and not others <plinss> we do use it in grid <fantasai> plinss, good point :) but not in :nth-child(), and in fact some of the :nth-child() patterns rely on us not processing negative indexes :/ SebastianZ: With the proposal of the "last" keyword we can also express ranges to an nth-last child. Tab said probably possible with second proposed syntax, but I don't think possible, but I disagree, since we're there focusing on the "n" which means the number of elements. <TabAtkins> once we drain the queue, I propose we take this back to the issue for syntax discussion oriol: With my proposal "n" is just the entity in the expression oriol: Going from the index of the last child .. oriol: If we want to express conditions to the end, constrain on the output seems more suited ntim: +1 to fremy about 2n+1 < 5 being hard to understand. ntim: Hope we don't end up with that <fremy> Can I suggest maybe to do like we did before in such cases, make a list of use cases, and then write how each proposal writes that range? fantasai: I was going to suggest table discussion until Friday. Tomorrow we'll have time for people to workshop ideas. We should do that tomorrow. TabAtkins: This is going too long, we should go back to the issue. SUMMARY: Will discuss syntax further in issue. CSS Values ========== scribe: fantasai Proposal: add sibling-count() and sibling-index() ------------------------------------------------- github: https://github.com/w3c/csswg-drafts/issues/4559 [bramus explains the proposal] <bramus> https://gist.github.com/bramus/45878ffc94a7318d63eb83a8882dfcc2 bramus: Right now they use various nasty selectors to achieve this bramus: It's really not great bramus: Something 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 staggered animations, where every sibling 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 bramus: I'm still proposing why authors need this argyle: There's lots of use cases. argyle: Dynamic color distances, dynamic [missed] argyle: recursion and tying things to position in the tree is fun argyle: sibling-index() and sibling-counter(), and child-count() argyle: these are static values that are about the leaf on the branch. They don't change, even if you change to display:none argyle: but gives many possibilities argyle: There's nasty selectors that do this, e.g. using :nth-child() with a lot of repetition argyle: also JS to do it, or template [missed] argyle: [explains how JS library works on this] argyle: New one recently proposed was child-count(). argyle: sibling-count() and sibling-index() are directly related to my tree position. Not introducing cycles argyle: container's child-count() is what you get from JS, CSS doesn't affect it argyle: but doesn't fulfill every use case, so in some cases need a filtered index argyle: e.g. if you have 30 items and filtered to 15 argyle: I guess I talked plenty emilio: Offhand this doesn't seem terribly problematic emilio: but it's not static emilio: not worse perf than :nth-child, but you need to invalidate anything that uses these functions whenever a sibling is added or moved emilio: not to say we shouldn't do it emilio: I'm a bit inclined to think that child-count() may not be so useful 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 .... emilio: needs to be optimized similarly to nth-child emilio: presumably these would go inside calc()? argyle: often <fremy> @ emilio, child-count() is useful if you want to divide a space or time (child-index() / child-count()) emilio: Other question would be, right now a lot of things assume numbers are resolved statically emilio: e.g. at parse time emilio: so on one hand, feel that this would be easier implementation-wise if we did it like variables emilio: but matter of implementation complexity emilio: I think this will take a lot more time if we do it in calc() than if we do it like variables emilio: which... is fine. argyle: Let me show you a demo <argyle> https://www.irccloud.com/pastebin/EsOxTEIg/ emilio: In variables, if you do like a custom property, then ? works <argyle> env() <argyle> yeah emilio: but then we need to keep things valid at parse time emilio: if you're using invalid stuff around sibling-index(), would have same error behavior as custom properties emilio: instead of falling back to previous declaration, you would get invalid-at-computed-value-time TabAtkins: I think this would be useful for reasons mentioned TabAtkins: only concern is implementation complexity and performance TabAtkins: e.g. this defeats style sharing TabAtkins: Discussing similar problem, dbaron explained the concerns TabAtkins: I'm not an implementer, can't express those concerns about perf. But there are performance footguns involved here emilio: The main perf issue, if you use sibling-index() etc., then every sibling gets its own style emilio: whereas if you do :nth-child(2n), then you can share styles between the things that match that rule emilio: It's not trivial to optimize it to preserve style sharing emilio: I guess :has() is worse TabAtkins: The things people do today, where people do explicit :nth-child()s, is just as bad TabAtkins: so the question is, would making this more likely to be used because it's easier? fremy: A lot of the ? are using this to make the demo work fremy: She has an inline style on every element that says, e.g. --index: 1; --index: 2; etc. fremy: what people do today is probably worse emilio: Main question is, does this make it too easy to do the wrong thing emilio: I'm not too concerned about style sharing in particular, more concerned about making it work in calc() or nth kind of thing emilio: Like attr(). It used to be a strongly-typed thing. Then we switched to more like variables emilio: we ended up deciding that fixing things was hard, so make it work like custom properties fantasai: You can't ever have an invalid output of siblings or sibling index TabAtkins: We changed attr() because you can have an invalid attribute that won't parse TabAtkins: having attr() as a length is more complex emilio: Well, it should be invalid for pseudo-elements emilio: What index would those be? emilio: it's not hard, it's a lot of work to fix <fremy> +1; sibling-index() in rgba() sounds like a great reason to make this a variable substitution <TabAtkins> nothing weirder about `rgba(sibling-index()...)` vs `rgba(sin(5) ...)` argyle: I'm curious about concatenation argyle: What if I want to create an ident that uses the sibling-index() argyle: is that invalid? it's not really a string I'm appending argyle: Also follow-up questions about nth-child syntax argyle: can I filter on a list and then get a sibling index of the filtered index argyle: to get the index after pre-filtering <bramus> seems like a follow up issue? fantasai: I can see the use-cases for that fantasai: like things with a [hidden], filter them out and use the index of what remains fantasai: you can't do an :nth-child() selector fantasai: but could do sibling-index(of <selector>) <argyle> this suffers from naive staggering https://codepen.io/argyleink/pen/VwBKjwj <argyle> this was one of the most requested features at CSS Day fantasai: I can def see the use-cases, and the perf concerns fantasai: last time we had something with similar profile was :has(), which stayed as a draft for a decade <bkardell> More than a decade :) 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 not Rossen: So proposal is to add to work on Values module 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. Rossen: any objections to adopt into Values 5, and then figure out if it's doable? dbaron: If we put it in a spec, likely to get implemented eventually even if 10-15 years later bramus: Authors want it. One of the most requested features bramus: #1 request at CSS Day bramus: People asked us to make it work Rossen: That's a pretty strong signal POLL: Add sibling-count() and sibling-index() to css-values-5 ED <fremy> yay, I think it can be made efficient <SebastianZ> Yay <argyle> yay <oriol> +1 <miriam> +1 <astearns> yea <fantasai> +1 <bramus> yes <florian> oui <rachelandrew> yes <TabAtkins> yes <changseok> yay <Rossen> да <ntim> Yes, but only once we sort out how this works in calc <fantasai> ntim, it just returns a number, right? <TabAtkins> (my suggested names were sibling-index(), sibling-count(), child-count(), and tree-depth() ) <hober> I don't think I can vote on this one way or the other without more data <argyle> just a number is all we need <tantek> +0 RESOLVED: Add sibling-count() and sibling-index() to css-values-5 ED meeting day: end
Received on Sunday, 10 September 2023 15:24:14 UTC