- 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