- From: CSS Meeting Bot via GitHub <sysbot+gh@w3.org>
- Date: Wed, 25 Jan 2023 16:35:47 +0000
- To: public-css-archive@w3.org
The CSS Working Group just discussed `Clearer definition of "nest-containing"`, and agreed to the following: * `RESOLVED: Relative-ness is decided based on & appearing *anywhere* in the selector, even nested inside anything else` * `RESOLVED: Option 2` <details><summary>The full IRC log of that discussion</summary> <fantasai> Subtopic: Clearer definition of "nest-containing"<br> <fantasai> github: https://github.com/w3c/csswg-drafts/issues/7972<br> <dbaron> Zoom for web is not working for me... I've tried multiple browsers at this point.<br> <dbaron> (doesn't work in either Chrome or Firefox)<br> <fantasai> TabAtkins: If a selector starts with a combinator, we assume relative selector<br> <fantasai> TabAtkins: insert & and interpret accordingly<br> <fantasai> TabAtkins: If no such combinator, we need to check if this should be relative selector or if there's an & deeper in<br> <fantasai> TabAtkins: Could have something like "foo &" or ":not(&) ..>"<br> <fantasai> TabAtkins: But spec is not super clear what it means by "contain" an &<br> <TabAtkins> :is(&:unknown, .foo)<br> <fantasai> TabAtkins: e.g. what happens if & is inside :is() within branch that's ignored by invalidity?<br> <fantasai> TabAtkins: is that &-containing or not?<br> <fantasai> TabAtkins: Depending on our answer, how does it affect serialization<br> <fantasai> TabAtkins: Listed a few options<br> <fantasai> TabAtkins: 1. Only look at top-level, not inside parens<br> <fantasai> TabAtkins: 2. Look everywhere except inside forgiving parsing list<br> <fantasai> TabAtkins: 3. Get deeper into parsing guts, say something about & inside even forgiving selector lists that might be invalid, and preserve that info across serialization even though normally drop such branches during reserialization<br> <fantasai> TabAtkins: fantasai and I thought #3 would be weird, because [missed]<br> <fantasai> TabAtkins: so initial suggestion was #1, simple suggestion<br> <fantasai> TabAtkins: after discussion with Natalie and Miriam, there were too many use cases for & deeper than top-level<br> <fantasai> TabAtkins: and having selector only in one branch and not others is weird and unusual, so not that important if behavior differs in branches<br> <dbaron> OK, given that the meeting link doesn't work for me in (a) Chrome/Mac (b) Firefox/Mac, and (c) Firefox/Linux, I'm going to give up for technical difficulties... see you at the regular call in 50 minutes.<br> <fantasai> TabAtkins: so suggestion is to look for & in every branch, invalid or not<br> <fantasai> TabAtkins: needs authors to be a little more careful<br> <fantasai> TabAtkins: but simple: if there's an & anywhere, it's got one<br> <fremy> q+<br> <fantasai> TabAtkins: Might need to tighten up parsing by having known-invalid selectors serialize as something particular<br> <fantasai> TabAtkins: So definition proposed is that it's containing an & if it contains an & anywhere<br> <fantasai> fremy: Tab mentioned that it's weird to have branches where some contain & but some do not<br> <fantasai> fremy: I agree, if you're doing that it's probably a mistake<br> <fantasai> fremy: But then why can't we make this a rule?<br> <fantasai> fremy: if you have a branching selector, have to have & in every branch<br> <dbaron> (ok, zoom started working when I clicked on the grayed-out "More ..." button at the bottom)<br> <fantasai> fremy: otherwise invalid<br> <fantasai> TabAtkins: Valid question, we could, but probably doesn't matter because unusual case<br> <fantasai> TabAtkins: so I don't think it's necessary<br> <fantasai> TabAtkins: but I could do either way<br> <Rossen_> ack fremy<br> <fantasai> fantasai asks for an example<br> <fantasai> TabAtkins: Consider the previous example, where only one branch of :is() has an &. Difference is we'd make that illegal<br> <TabAtkins> so `:is(&:unknown, .foo)` would be an invalid selector<br> <fantasai> TabAtkins: Also weird, it would be the only way for :is() to invalidate a selector<br> <lea> in case it helps, as an author, I'd expect .foo { :is(&, .bar) {} } to be interpreted as .foo, .foo .bar , not .foo, .bar<br> <fantasai> TabAtkins: another little bit of complexity that we could avoid for a corner case<br> <fantasai> fremy: Yes, I think I agree. It might not make much sense, but you might want it<br> <fantasai> TabAtkins: Lea posts a different suggestion, which is that you take different paths in deciding relative selector or not<br> <fantasai> TabAtkins: Problem is that doesn't map directly to :is() notation, so suspect it would complexify implementations<br> <chris> leaverou there was a question for you<br> <fantasai> fantasai: Do we have any comments from implementers on lea's question?<br> <lea> chris: what was it? I'm looking at the minutes but can't find it. I'm not on the call, as I'm on the TAG plenary<br> <fantasai> TabAtkins: I can't say for sure, but I think our implementation would find it difficult<br> <fantasai> s/sure/sure because our implementers aren't on the call/<br> <fantasai> emilio: Doing what Lea suggests would be fairly annoying<br> <fremy> @ lea, the question was whether TabAtkins's reply to you addressed your concern or not<br> <fantasai> emilio: and could have problems with selectors growing exponentially, which is not great<br> <fantasai> emilio: I think this is a problem Blink had when they initially implemented this<br> <fantasai> TabAtkins: When trying to do naive impleementation of :is(), it was a problem<br> <fremy> @ lea, and (I guess) whether this was something you felt strongly about<br> <lea> fremy: no, this is not something I feel strongly about<br> <fantasai> Rossen_: Current proposal is simply option 3 without any further modification (and by option 3 we mean option 3 in IRC, which is option 2 in the issue)<br> <TabAtkins> proposed resolution: Relative-ness is decided based on & appearing *anywhere* in the selector, including in (potentially-invalid) branches of a forgiving-selector-list<br> <fantasai> plinss: I presume it's only legal for one & in selector?<br> <fantasai> TabAtkins: no can have multiple<br> <fantasai> plinss: so I can say &.foo &.bar?<br> <lea> though I do find it fairly weird if you can "break" out of the nest by doing `:is(&, .bar)`. and if :is(.bar) matches different things than the .bar in :is(&, .bar)<br> <fantasai> TabAtkins: & represents elements matched by the parent selector<br> <fantasai> TabAtkins: would be two different elements that both happen to match the same parent<br> <fantasai> plinss: fair enough<br> <Rossen_> ack fantasai<br> <TabAtkins> fantasai: suggest we clarify that if I have any kind of selector garbage inside :is(), including an & nested deep inside of the garbage, that & is considered to be an & for these purposes?<br> <TabAtkins> TabAtkins: correct<br> <fantasai> :is(:unknown(&))<br> <fantasai> :is([something (&something else { } ) ])<br> <TabAtkins> :is([{(&)}]) has an ampersand in it, per the suggested resolution<br> <fantasai> TabAtkins: If during selector parsing you see an & delim token, mark the selector as having an & and continue normal parsing<br> <fantasai> Rossen_: any other feedback?<br> <fantasai> RESOLVED: Relative-ness is decided based on & appearing *anywhere* in the selector, even nested inside anything else<br> <fantasai> TabAtkins: Question is what to do about serialization<br> <fantasai> TabAtkins: Option 1: do nothing special. This might mean that an invalid branch is dropped, which changes selector interpretation<br> <fantasai> TabAtkins: Option 2: serialize any :is() branch that contains an & as-is<br> <fantasai> TabAtkins: Option 3: serialize any :is() branch that contains & as something guaranteed to be invalid, e.g. "&:not(&)" (which is guaranteed to not match but definitely contains an &)<br> <emeyer> q+<br> <fantasai> emilio: Only doing ????<br> <fantasai> TabAtkins: Option 4: do 2 or 3 if that's the only branch that contains an & (and thus the selector interpretation is dependent on that branch existing)<br> <Rossen_> ack emeyer<br> <fantasai> emeyer: wrt option 1, what are the concerns?<br> <fantasai> emilio: It's bad if something serializes and then whe you re-parse it it's interpreted differenly than the original<br> <fantasai> TabAtkins: So you can have a selector that's relative in new browsers and non-relative in older browesers, which is significant change<br> <fantasai> emilio: You lose the forgiveness ... which is annoying<br> <fantasai> [missed]<br> <dbaron> My preferences: definitely not option 1, weakly prefer option 3 (without the option 4 variant).<br> <fantasai> emilio: Implementationwise, it feels like it would be nice not to account for & in invalid branches, so you can compute the relativeness of a selector independently of the parsing process<br> <fantasai> <fantasai> +1 dbaron<br> <fantasai> emilio: ... but all the options are weird in their own way<br> <Rossen_> q?<br> <fremy> @ TabAtkins, for option 3 `&:not(&)` might be costly to compute, how about something truly invalid like `::-invalid-(&)`<br> <fantasai> [Tabatkins summarizes dbaron's comment into audio]<br> <fantasai> plinss: [asks about option 2]<br> <fantasai> emeyer: option 2 is consistent with media queries, where we preserve the CSS string for general enclosed<br> <fantasai> TabAtkins: fair<br> <emilio> s/emeyer/emilio<br> <fantasai> [Leaning towards 2 or 3]<br> <dbaron> I'm also fine with 2.<br> <fantasai> Straw Poll: Option 2 vs Option 3<br> <TabAtkins> abstain<br> <fantasai> abstain (defer to implementers)<br> <emilio> either wfm<br> <plinss> 2<br> <lea> 2 (based on the descriptions in the comment primarily, as I've missed a lot of the discussion due to being on another call)<br> <Rossen_> 3, 2<br> <fremy> abstain<br> <emeyer> abstain<br> <chris> abstain<br> <davidleininger> 2<br> <dbaron> abstain<br> <florian> abstain<br> <jensimmons> abstain<br> <fantasai> emilio: other issue of option 2 is that it changes behavior from today<br> <fantasai> TabAtkins: in theory, yes, if someone is putting & inside their invalid :is() selector, it will change serialization<br> <fantasai> emilio: We probalby want to do it for all invalid selectors, so that :unknown is reserialized as-is, regardless of &<br> <fantasai> TabAtkins: I suggest taking up separately<br> <fantasai> Proposed to go with option 2<br> <fantasai> and emilio to open issue about switching serialization for all selectors<br> <fantasai> plinss: In my mind, would want to be consistent for all selectors<br> <fantasai> TabAtkins: I agree in theory, don't care too much<br> <fantasai> RESOLVED: Option 2<br> <fantasai> TabAtkins: open separate issue for the rest, because it may have a compat risk<br> <fantasai> plinss: If the other one goes the other way, might want to revert this one<br> <fantasai> TabAtkins: currently don't have compat either way for & stuff<br> <fantasai> plinss: Yes, but I want us to note in the other issue to reconsider this one<br> <emilio> I can open the issue<br> <fantasai> ACTION: emilio to open new issue<br> </details> -- GitHub Notification of comment by css-meeting-bot Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7972#issuecomment-1403898638 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Wednesday, 25 January 2023 16:35:49 UTC