w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.38k stars 641 forks source link

[css-nesting] Problem with mixing properties and selectors #8249

Closed plinss closed 1 year ago

plinss commented 1 year ago

As mentioned I'm opening a new issue to outline the objections I raised in the call today and to discuss paths forward.

My primary objection to the current syntax is that mixing properties and selectors without a clear distinction places unacceptable (to me) restrictions on the future design of the CSS language.

An implementation parsing a style declaration will need to presume anything that doesn't start with an identifier or function is a selector, which restricts our ability to ever extend property declarations with anything that doesn't start with an identifier or function. Furthermore this restricts our ability to ever extend the definition of an identifier or a function. As an example, if this were implemented first, we could never have added custom properties with the current syntax (which redefined identifiers).

Alternatively, we could limit selector combinators to the current set and a limit extension path, like /<name>/, this would place restrictions on future selector syntax and potentially add more confusion as to the rule of when a & or the :is() hack is required. Not a fan of this.

I see two paths forward (and welcome other suggestions):

1) We remove the lookahead restrictions on the parser and 'simply' adopt the SASS syntax. The lookahead restriction came about 25 years ago when there were real concerns that CSS would be too slow to ever implement in a browser and everything was focused on performance. I'd like to see some experimentation and real-world data to check that assumption and see if advancements in processor speed and RAM availability allow us to relax that.

2) We add something that clearly distinguishes selectors from properties within a style declaration.

Something like:

div {
  color: red;
  @nest span {
    color: blue;
  }

is fine by me, but I accept that this has been proposed in the past and rejected.

A compromise I'd be OK with would be treating a bare @ inside a declaration as the equivalent to @nest (and possibly allowing @nest to be optional for those wanting clarity). This is functionally equivalent to requiring the & (which many people in the polls preferred), but also handles cases where the & isn't the start of the selector without adding lookahead. e.g.:

div {
  color: red;
  @ span {
    color: blue;
  }
  @ &:hover {
    color: green;
  }
  @ section & {
    color: yellow;
  }
}

This leverages the fact that @ is already CSS's universal escape hatch and clearly distinguishes properties and selectors, allowing unrestricted extensions of either in the future. It also minimizes verbosity as the majority of nested selectors can simply start with an @ and requires no other changes or special rules to learn.

tabatkins commented 1 year ago

As an example, if this were implemented first, we could never have added custom properties with the current syntax (which redefined identifiers).

This isn't accurate. We couldn't have naively redefined identifiers; we'd have had to do some compat analysis to check if it would actually cause a problem or not. (And we'd have found it was perfectly okay, since --foo wouldn't be the start of any valid selector anyway, so usage would be minimal.)

The hard restriction we have is that we can't introduce new property syntax that looks like a (relative) selector. So nothing that puts any of >+~.:#[ at the start, for example. (.:# could be used if followed by whitespace or some other non-ident, tho.)

(Unless we end up solving the perf problems with the unbounded lookahead. Then we can potentially do a lot more so long as they're eventually distinguishable, tho we'd likely still want to be careful about mixing things too hard.)

Alternatively, we could limit selector combinators to the current set

This won't help, as descendant combinators mean the nested selector can start with any of the simple selector glyphs (.:#[). We'd also have to restrict our ability to add new simple selectors, not just combinators.


"Mandatory @nest" was rejected by the group already, and verbosity wasn't the sole concern about it; copy/paste ability is still affected even if you reduce the required prefix to a single character.

jensimmons commented 1 year ago
  1. We remove the lookahead restrictions on the parser and 'simply' adopt the SASS syntax… I'd like to see some experimentation and real-world data to check that assumption and see if advancements in processor speed and RAM availability allow us to relax that.

I believe everyone agrees that removing the lookahead restrictions on the parser and adopting SASS-style syntax would be ideal. This is not something for which we can debate the pros and cons. It's all pros.

Implementation experience is the only path forward to find out whether or not if this is a viable alternative. The teams currently implementing CSS Nesting need to try it, test performance, and see what happens. To attempt to figure out a way to make it fast. If so — fantastic, decision made. If not, well, decision made.

I know folks are already working to see such implementation experience happen. Meanwhile, we should discuss what to do if removing the lookahead restrictions is not a viable solution.

fantasai commented 1 year ago

@tabatkins and I both disagree that splitting style rule and declaration parsing on non-ident start over-restricts the future of CSS declaration syntax. But to understand why, we need to consider:

We're not just reserving everything that has an ident start for declarations: we're reserving everything that results in an invalid sequence, whether that sequence is parsed in as invalid style declarations or invalid style rules or a mix of both.

Remember the parsing rules being proposed for mixed context are a little different:

The following sequences are all complete invalid constructs: they are thrown away and anything after them starts a new parse. Which means we can interpret them however we want in the future.

@foo anything except semicolon { anything }
random stuff: other stuff { anything } anything;
random(stuff): other stuff;
!other stuff: more stuff;
++extra stuff: stuff;
(anything): anything;

The only thing we're closing off entirely is a new construct that maps to the following sequence:

  1. a sequence that starts with a symbol (and thus triggers style rule parse)
  2. a {}-block (which thus ends the style rule parse)
  3. a sequence that is currently a valid style rule or valid property declaration (which then gets read in as valid by current browsers)

Basically, we can't introduce new things like:

#stuff starting with a symbol { anything in this block } valid-property: value;
/* new thing all parsed as one declaration */

which doesn't seem very likely for us to add in the first place.

So as long as we're not planning to introduce a new type of property declaration that maps to that, we can introduce any new declaration syntax additions we want in the future. Though for the sake of preserving LALR parsing, we'll want any symbol start to be something that is not currently valid as a selector start token.

I think this is plenty of open space for innovation.

plinss commented 1 year ago

"Mandatory @nest" was rejected by the group already, and verbosity wasn't the sole concern about it; copy/paste ability is still affected even if you reduce the required prefix to a single character.

Yet a significant number of poll respondents advocated for a mandatory & which has the same copy/paste problem, yet seems to be acceptable to developers.

plinss commented 1 year ago

One of my opinions on this whole matter is that what people really want is SASS's behavior, if we can't give them that, then giving them something that's kinda close but has all sorts of weird rules and exception cases (and requires ugly hacks like wrapping perfectly normal selectors in :is() for syntactical purposes) isn't all that helpful in the end.

If people don't like what we deliver and prefer SASS, they can just use SASS. What we deliver should be consistent, logical, easy to explain, and not constrain the future development of the language in any way just to try to mimic a syntax that we really can't mimic properly.

tabatkins commented 1 year ago

giving them something that's kinda close but has all sorts of weird rules and exception cases

Hyperbole isn't useful here. There is precisely one rule - if your selector starts with an ident, you have to rephrase it somehow.

plinss commented 1 year ago

Not trying to be hyperbolic, and it's not one rule if the answer is 'somehow'. First, authors have to understand exactly what an ident is, then sometimes you have to use a leading &, and other times you have to wrap at least the leading selector in :is() (and yes, that's a hack). Sorry, but that's weird, and while the reasons make sense to us, they won't make sense to most authors. Then, in the future as we add more selector syntax or property syntax the set of rules and exception cases can grow. That's problematic.

tabatkins commented 1 year ago

"what's an ident" is extremely simple - if it starts with a letter or a dash (and isn't a number). "it feels like a keyword" works just fine for author intuition.

For fixing it, you can do :is() all the time. Appending a & compound is just shorter sometimes. That said, I've just posted a suggestion in #8253 that allows for a completely uniform super-short fix.

plinss commented 1 year ago

My point about idents isn't that it's hard, it's that it's one more thing. i.e. the syntax exceptions aren't 'just one simple rule'. (Also, you forgot that idents can start with escapes, underscores, and non-ascii... In Jenn's poll, she even got the description of when an & is necessary wrong, as she forgot custom properties. So don't try to tell me this ins't error-prone.)

The rules at this point are: 1) if your selector doesn't start with an ident, use as-is (and know what an ident is), or optionally prefix with & 2) if it starts with an ident, you must prefix with & 3) unless you need to use & somewhere else inside your selector, the wrap the first selector in :is()

(And, really, is adding :is() all the time an improvement? I know you're not seriously expecting people to just always wrap the first selector in :is(), but I can see tools doing it.)

Prepending every nested rule with @ actually is one simple rule and there's no special casing, ever. Every selector syntax available now or in the future 'just works' (we already excluded @ from selectors) and there are no conflicts with future extensions to property syntax.

LeaVerou commented 1 year ago

@plinss

We remove the lookahead restrictions on the parser and 'simply' adopt the SASS syntax. The lookahead restriction came about 25 years ago when there were real concerns that CSS would be too slow to ever implement in a browser and everything was focused on performance. I'd like to see some experimentation and real-world data to check that assumption and see if advancements in processor speed and RAM availability allow us to relax that.

I agree and I have opened an issue about this here with an algorithm that would minimize the performance hit: #7961 Here is a summary:

Sadly the issue was later derailed a bit by those who think & should be mandatory.
One real issue that came out of it was (raised by @lilles) that we'd have to make {} invalid in custom properties for that to work, and there is some limited usage of that in the wild (<0.01%), so it's a tradeoff. (IMO still a worthy one).

@jensimmons

Implementation experience is the only path forward to find out whether or not if this is a viable alternative. The teams currently implementing CSS Nesting need to try it, test performance, and see what happens. To attempt to figure out a way to make it fast. If so — fantastic, decision made. If not, well, decision made. I know folks are already working to see such implementation experience happen.

See above, when I tried to discuss it in #7961, the Google implementor was very negative:

I don't share this goal; I would like us to just get the syntax (any syntax) specified, out the door and be done with it. So no, I won't be spending resources trying to bend our minds around how we tokenize CSS to this avail; I can NAK what is a non-starter for us, and that's what you'll get.

Great to hear things have changed since then and folks are working on it. Is it the same folks? Which folks are working on it?

bramus commented 1 year ago

In my mind, a merged version of options 3 and 1 tick all the boxes for trying to detect nesting:

  1. Starts with any of the existing combinators >+~? You’re nesting.
  2. Starts with a selector that starts with a symbol.:#[*? You’re nesting.
  3. Starts with the new & combinator? You’re nesting.
  4. Starts with @nest (to be used if you want to use & somewhere but not at the start)? You’re nesting.

Anything else would fall back to the current mechanism to detect declarations, nested at-rules, etc.

Rules 3 and 4 in the list of checks above are the bail out mechanism for when an element selector is nested, similar to what option 1 of the syntax provided us with. These two rules (3 and 4) also play nice with the first two rules, as they can be used together: for example teams can choose to make @nest mandatory by using a linter, while giving other people the freedom to not do so.

(Note that I’m sticking with @nest instead of @ for reasons explained here)

bradkemper commented 1 year ago

As an author myself, who has written a lot of CSS both with and without SASS, I don't find these restrictions and workarounds confusing at all. Once people do it a few times they will quickly get used to it. It isn't like even SASS didn't also have things to keep in mind: like always have a semicolon after the last declaration before the nested selectors start. That one still trips me up sometimes, but I know to look for it when there is a problem. And if I have to choose between ALWAYS preceding each rule with @ or @nest, or just doing it when the selector starts with a letter (or underscore, ideograph, or dash or escape), then I'd much much prefer the latter.

Sure something like :is(div) is ugly and sort of a hack, which is why I would like to be able to choose a bare @ as an non-mandatory prefix instead, but even without that I'd like to move forward with what we have. I don't think it is at all burdensome to the author.

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed CSS Nesting Syntax, and agreed to the following:

The full IRC log of that discussion <fantasai> Topic: CSS Nesting Syntax
<fantasai> github: https://github.com/w3c/csswg-drafts/issues/8249
<chris> resolving two color issues in <10min is unprecedented
<fantasai> TabAtkins: I'm willing to summarize what I believe plinss's position is, he can correct
<fantasai> TabAtkins: fear is that the direction the spec is specifying will overly constrain future CSS
<fantasai> TabAtkins: certain new syntactical things in properties or selectors
<fantasai> TabAtkins: proposal is instead to have a dedicated syntax to mark things as a selector
<fantasai> TabAtkins: that way all future syntactical developments would still be allowed
<lea> q?
<fantasai> TabAtkins: and future developments for selectors, which might currently conflict with properties, would also be allowed
<fantasai> TabAtkins: because you have a glyph to mark it as a selector
<fantasai> TabAtkins: related is the 8251 issue, where dbaron discusses the things that trigger selector processing and not currently used by selectors
<fantasai> TabAtkins: this issue accepts mixing of properties and selectors in grammar space
<fantasai> TabAtkins: issue is, we've already discussed previously, what peter is suggesting
<fantasai> TabAtkins: this was Option 1, you had to start with & or @nest or various variants thereof
<fantasai> TabAtkins: This was rejected by WG for verbosity and for copy-paste limitations
<fantasai> TabAtkins: core issue is, WG has looked over that syntax direction and rejected it in the past
<jensimmons> q+
<fantasai> TabAtkins: so I would like to re-affirm that decision, that we're not going to use a dedicated marker syntax of some kind to denote selectors and separate them from properties
<fantasai> TabAtkins: but rather go with current approach of mixing the space
<lea> q+
<fantasai> TabAtkins: make sure the Syntax spec creates a clear dividing line
<TabAtkins> fantasai: I think something Tab didn't emphasize is the core part of Peter's concern for forward compat
<TabAtkins> fantasai: The real effect of forwards compat isn't as - we'r enot limiting as much as it seems like we are
<TabAtkins> fantasai: What we're allowing for the future is anything that's invalid, regardless fo whether it's currently property or selector
<TabAtkins> fantasai: The space of "what is invaidl junk" is actually really broad even with our current proposal
<Rossen_> ack fantasai
<Zakim> fantasai, you wanted to react to ntim
<fantasai> https://github.com/w3c/csswg-drafts/issues/8249#issuecomment-1362033982
<TabAtkins> fantasai: The ony thing we can't expand into is a super-limited syntax space that I can't imagine us actually doing
<fantasai> #stuff starting with a symbol { anything in this block } valid-property: value;
<TabAtkins> fantasai: We cant' start with a symbol, *and* has a curly-brace block *and* is followed by something tha tlooks like a property
<TabAtkins> fantasai: This is the only thing you can't define in the future is a cool new feature
<TabAtkins> fantasai: If it doesn't look like that it's invalid - whether a property or style rule, we throw it out
<TabAtkins> fantasai: And in th efuture we can call it valid either way
<TabAtkins> fantasai: So for concern abou tpainting us into a corner, it's acutally a very small corner and the rest of the space is open
<fantasai> plinss: Just want to clarify a couple points, most of what Tab said is accurate
<fantasai> plinss: it's not necessarily required to have a solution that prefixes every single rule
<fantasai> plinss: also fine to create a new scope
<fantasai> plinss: just nested brackets or whatever, that also solves the copy-paste problem
<fantasai> plinss: just want something that delineates the syntax space
<fantasai> plinss: we did resolve not to do this in the past, but I'm not sure that took everything into account
<fantasai> plinss: not locked by previous decision
<astearns> +1 to not taking older @nest decision as final
<fantasai> jensimmons: I did hear plinss's concerns, and we've discussed exhaustively
<fantasai> jensimmons: but despite downsides, I see all the momentum going towards Option 3 including from webdevs
<Rossen_> ack jensimmons
<fantasai> jensimmons: There was a lot of conversations after ?? meeting, and I appreciate dbaron, fantasai, TabAtkins investigating what we would limit ourslves
<TabAtkins> s/??/final December/
<plinss> q+
<fantasai> jensimmons: but it seems we're not really limiting ourselves, so I think should move forward
<fantasai> jensimmons: want a path that moves us forward and is realistic and acceptable
<Rossen_> ack lea
<fantasai> lea: A lot of things I wanted to say were mentioned by fantasai, still have a lot of space for expansion
<fantasai> lea: but we could expand that space even further by reserving some characters
<Rossen_> ack plinss
<fantasai> plinss: I'm not sure I buy fantasai's argument
<fantasai> plinss: it's not infinite, but there are cases where we wanted to do something but couldn't because shows up in the wild as some weird hack
<fantasai> plinss: I think it'll be limiting
<fantasai> plinss: example is custom properties, couldn't have done that if we had done this first
<fantasai> plinss: I don't want us to get into that situation
<TabAtkins> fantasai: Lets take the custom property eample
<Rossen_> ack fantasai
<Zakim> fantasai, you wanted to respond
<TabAtkins> fantasai: say initial hypthen switched us to selector parsing
<TabAtkins> fantasai: we could do it
<Rossen_> Zakim, close queue
<Zakim> ok, Rossen_, the speaker queue is closed
<TabAtkins> fantasai: You'd throw it out as an invalid selector today
<TabAtkins> fantasai: And that means we can reinterpret it later
<TabAtkins> fantasai: Have you really looked at what the limiting case is?
<TabAtkins> fantasai: The ocnditions are really strict. anything that's currently invalid and gets thrown out, we can reinterpret
<TabAtkins> fantasai: have to keep in mind that the parsing in the nested context isnt' the same as top-level, we truncate at top-level semicolon even in selecto rparsing
<lea> *Nesting itself* is a case where past syntax limits us in what we can do syntactically (going back, maybe we should have used something other than a colon for pseudos), but it's not an insurmountable problem, we are designing around it. We'll design around these issues in the future too, if they come up.
<TabAtkins> fantasai: So there's very limited - can't think of anything you want to do that'll cause a problem
<lea> q?
<lea> q+
<fantasai> plinss: we could solve this with lookahead
<fantasai> plinss: also concerned that we have stuff that's valid for selectors and can't re-use for properties
<fantasai> plinss: selectors can be really really really long, especialy with lists of selectors
<argyle> q+
<fantasai> plinss: thing at the end that changes selector or property, could get into situation that we cant solve without a lot of lookahead
<fantasai> Rossen_: I've closed the queue, 2min past the hour
<lea> regarding exploring lookahead, I tried. Here's a summary: https://github.com/w3c/csswg-drafts/issues/8249#issuecomment-1362739063
<fantasai> Rossen_: Strong arguments in both directions
<fantasai> Rossen_: alan proposed we make nesting an additional call, can make it as soon as next week e.g. 1hr before the main CSS call
<fantasai> Rossen_: but right now we don't seem to have consensus
<lea> +1 to Nesting breakout
<fantasai> Rossen_: or we can take a resolution and ask Peter to file a formal objection
<fantasai> TabAtkins: I would prefer to get the formal objection filed now if it's going to be filed, would rather not be in limbo
<lea> let's try to avoid a FO as much as we can, the TAG is already overworked :(
<fantasai> TabAtkins: fantasai and I explored the syntax space carefully, we don't think there's a real limitation there
<astearns> have to drop
<fantasai> TabAtkins: so I don't think further discussion will yield anything useful
<lea> we need a Nesting breakout even regardless of the FO, don't we? So let's schedule that
<fantasai> Rossen_: ok, we'll try to have a call for nesting, whether this topic is part of it or not is TBD
<fantasai> Rossen_: I will call for objections, and then have a resolution that seems supported by rest of group
<fantasai> Rossen_: Any objections?
<fantasai> plinss: I clearly object. More than happen to have the long call or breakout or sub-breakout or whatever
<fantasai> plinss: happy to let Tab and fantasai convince me that I'm wrong
<fantasai> plinss: and to change my mind
<oriol> I'm more on Peter's side on this topic
<fantasai> plinss: but shy of that, or changing the processing rules, I sustain my objection
<fantasai> Rossen_: It does seem this has been discussed over and over, and I hear support for this from many people
<fantasai> Rossen_: so suggest we resolve this, or take up as additional changes to the current resolution
<fantasai> plinss: We've resolved on Option 3 with this issue open
<fantasai> plinss: still saying we can discuss at the breakout call, so what's point of resolving?
<fantasai> Rossen_: we resolved to discount other options, not to adopt Option 3
<fantasai> [some discussion of what we resolved or didn't]
<fantasai> jensimmons: would be helpful to take the temperature of the room
<lea> fwiw, I agree with plinss that lookahead should be explored more. But not primarily for futureproofing (I think there's enough syntax space that we're not painting ourselves into a corner), but primarily for syntax ergonomics. I'm not convinced it's an unsolvable problem.
<fantasai> fantasai: straw poll, and then close discussion until next week?
<fantasai> Rossen_: A = support Option 3, and B = not support it
<argyle> A
<jensimmons> A
<ydaniv> A
<TabAtkins> A
<fantasai> A
<oriol> B
<bradk> A
<SebastianZ> A
<miriam> A
<plinss> B
<dholbert> A
<GameMaker> A
<flackr> A
<davidleininger> A
<futhark> A
<florian> A
<lea> I find the question unclear, so I'm not voting.
<lea> A
<Rossen_> A
<fantasai> Rossen_: pretty strong signal here, let's go ahead and record this as a resolution. We will try to get the extra nesting discussions, Peter I'm hoping you can proceed with next steps if you want to pursue formal objection or wait until next week
<fantasai> plinss: happy to discuss on breakout call, but want to actually get to it
<fantasai> Rossen_: we've never had a rule that we can't re-open previous resolutions :)
<fantasai> plinss: that's been teh arugment several times
<fantasai> florian: from the other angle, if you do file an FO and are subsequently convinced, you can retract it
<fantasai> plinss: if discusisng in a week, don't need to file an objection today
<fantasai> Rossen_: We'll schedule for next week then
<fantasai> jensimmons: please schedule for next week, it's quite importnat to us
<fantasai> RESOLVED: Adopt Option 3
<fantasai> Rossen_: I appreciate everyone staying longer than usual, we don't almost ever, but this is an important topic to many
<fantasai> Rossen_: we'll schedule an additional meeting next week
tabatkins commented 1 year ago

I'd like to point back to @fantasai's comment about what precisely the syntax constraints we're actually adopting are.

There are two aspects: things that are currently valid, and things that are currently invalid.

For things that are currently valid, we are indeed closing the door on options. With the current spec, we cannot allow a declaration to start with +, for example, as that's a valid relative selector. (At least, not without paying a lookahead tax that we're currently rejecting.) We cannot start a selector with an ident. As I've said in previous threads, tho, starting a declaration with a symbol is already very likely off the table, given the prevalence of people using a random ascii symbol to "comment out" a property. So in practice we're closing the door on very little new space that wasn't already verboten.

For things are the currently invalid, we are in general not closing the door on anything. CSS's existing forward compatibility parsing rules give us a lot of leeway to reinterpret things, ensuring that "new stuff" (aka invalid stuff in an older browser) gets properly isolated and ignored without screwing up surrounding stuff that is recognized in an older browser.

The recovery rules are:

This suggests that (a) we want to bias toward parsing unknown things as nested rules, since the recovery is stricter/safer, and (b) if an older browser parses some pattern as an (invalid) nested rule, and we decide to make that pattern a declaration instead, this is fine so long as it doesn't contain a {}-block followed by something that looks like a complete (prop:val;) declaration.

That's the crux. The pattern we are locking ourselves out of is just %foo: {...} bar: baz; being parsed as a declaration. That is such a ridiculously arcane pattern that I feel completely comfortable stating we'd never explore that space anyway, even if it did continue to be an option.

Notably, say in the future we decide that 1: red; should be a valid declaration. Currently that'll trigger nested-rule parsing, but the semicolon will cause us to stop parsing and throw it out as an invalid construct, then resume parsing fresh afterwards. If we changed the rules so that browsers parsed that as a declaration, then older browsers will... see it as invalid, and throw away tokens until the semicolon, then restart parsing fresh. In other words, we have precisely identical error-recovery regardless of how it's categorized in older browsers.

Loirooriol commented 1 year ago

starting a declaration with a symbol is already very likely off the table, given the prevalence of people using a random ascii symbol to "comment out" a property.

I'm not convinced by this, because 1) I don't see this statement backed by any data, and 2) a declaration preceded by a random symbol may stay as invalid even if we add a new feature that uses that same symbol.

Like, even if there is plenty of +width: 10px on the wild, we might be able to add a new future that does something special for e.g. +width+: 10px. Option 3 without lookahead closes that door.

plinss commented 1 year ago

A problem I have with the "it's only an error recovery problem" approach, is that once something new gets added to selectors or properties, it's closed off forever in use for the other case. For example, if we add % as a special prefix for properties, we can never use it as a combinator (or vice versa). And that's not even considering cases we're already closing off, e.g. IIRC there's a proposal for extending list properties like: +backrgound: green;, kiss that goodbye before it's even properly considered.

I still feel that's too constraining. Paraphrasing as I believe @Loirooriol said elsewhere, we are bending and constraining the language here in ways that are restrictive, and introducing new (and seemingly arbitrary to the non-initiated) rules that authors have to learn and follow, all for the benefit of avoiding a single character. (And if we chose a mandatory & prefix, it just choosing a different character.) I just don't see the benefit being worth the cost.

And frankly, I don't think the copy/paste argument has all that much merit. As the proposal stands, authors cannot 'simply' copy paste rules into a nested context because they will have to manually scan them for the cases that need fixups, this will be error-prone. Big picture, I don't think we're really helping authors here. If authors have to add a simple prefix, that can be easily automated by tooling.

Other solutions that satisfy my concerns that I'm not sure have been properly considered are creating a nested rule context within an existing style rule, e.g.:

foo {
  color: red;
  @nest {
     bar { color: blue; }
     baz { color: green; }
  }
}

Which could be simplified to:

foo {
  color: red;
  @ {
     bar { color: blue; }
     baz { color: green; }
  }
}

or even:

foo {
  color: red;
  {
     bar { color: blue; }
     baz { color: green; }
  }
}

A solution like the above does simplify copy/paste and avoids all the syntax rules and extension issues. (It also doesn't preclude allowing @ bar { ... } for individual nested rules.)

jensimmons commented 1 year ago

starting a declaration with a symbol is already very likely off the table, given the prevalence of people using a random ascii symbol to "comment out" a property.

I'm not convinced by this, because 1) I don't see this statement backed by any data

I worked as a lead front-end dev in China for three months, in two cities with two development different teams. And it was mind-blowing for me what they were doing in their CSS. It was so different than what I was used to, even though I'd already worked with many dozens of different teams, on hundreds of projects, in multiple countries across Europe and North America, over two decades. And yes, I saw code that had random ASCII symbols all over the place to comment things out, or make them work one way for one version of IE while another way for another version of IE. The experience taught me there's an incredibly wide variety of how people write their CSS. Especially given how many web developers do not speak English — there's a lot of diversity and variety in what's considered "best practice" in one community / country / continent vs another.

Loirooriol commented 1 year ago

@plinss That other solution was discussed in #4748, even initially approved in https://github.com/w3c/csswg-drafts/issues/4748#issuecomment-960145492, but reverted in https://github.com/w3c/csswg-drafts/issues/4748#issuecomment-1233176065. IIRC the concern was that it uses 2 levels of indentation, which can be inconvenient when having multiple levels of nested rules.

I guess I would prefer it over option 3 (which yeah, I feel like it's bending the language too much for little gain), but postponing the brackets instead of nesting them (i.e. option 4) avoided the double indentation so it was probably better.

@jensimmons I don't doubt that there are some people doing this kind of things, but I lack numbers to know if these are only some anecdotical cases, or if the breakage of adding a feature mixing symbols with declarations would be huge. Also, there might have been people using -- to comment out a declaration, but this didn't prevent custom properties since the effect is not observable unless you use var() or JS APIs. So I'm not convinced that adding such new features is "very likely off the table" as Tab said.

plinss commented 1 year ago

I accept that using a nested block looks weird when the outer most rule is only a nesting container due to {{ ... }}, but for that case we can always also accept the top-level @nest syntax. I'm not convinced the extra level of indentation should be a deal-breaker (it certainly isn't worth adding the language constraints just to avoid IMO).

I understand that alternative approaches were discussed and rejected in the past, but it's not clear that all of those decisions were made with the same information as we now have. I strongly suspect some of those would have gone differently were we making them now. If we're going to get past this impasse we all need to be able to take a step back and look at the big picture.

I fear that many of the advocates of the current approach have gotten there by a long series of compromises trying to narrow down the options, which each may have made sense in isolation, but when taken in as a whole have led us to a solution where the costs outweigh the benefits.

jensimmons commented 1 year ago

I lack numbers

A Google search for "CSS star hack" returns 9.8 million results.

plinss commented 1 year ago

I lack numbers

A Google search for "CSS star hack" returns 9.8 million results.

It only returns 1660 results if you quote the phrase. And the majority of those talk about specifically targeting IE7 and below and are 9+ years old

yisibl commented 1 year ago

With all due respect, @ is too much hack.

And yes, I saw code that had random ASCII symbols all over the place to comment things out, or make them work one way for one version of IE while another way for another version of IE.

@jensimmons As a Chinese developer, I'm curious about what kind of CSS, do you have an example?

tabatkins commented 1 year ago

I fear that many of the advocates of the current approach have gotten there by a long series of compromises trying to narrow down the options, which each may have made sense in isolation, but when taken in as a whole have led us to a solution where the costs outweigh the benefits.

This is not the case, and speculation of this sort isn't helpful. I know exactly what the costs are in aggregate (I laid them out in my last comment), and believe they are more than acceptable vs the costs of using a syntax that diverges from the common usage of nesting across more than a decade of preprocessors (and possibly introduces additional levels of indentation to every usage of nesting).

I know you disagree, @plinss, but if my previous post hasn't convinced you I'm not sure anything else will. I personally am not going to be convinced to go back to a mandatory prefix or additional nesting, either, and there's no middle ground between our two positions to make a compromise possible, so I suggest you go ahead and file your objection if you're going to.

tabatkins commented 1 year ago

I'm curious about what kind of CSS, do you have an example?

For example, check out this list of Internet Explorer parsing hacks.

And in my personal experience I've absolutely used //color, *color, or #color to "comment" a property out.

tabatkins commented 1 year ago

Like, even if there is plenty of +width: 10px on the wild, we might be able to add a new future that does something special for e.g. +width+: 10px. Option 3 without lookahead closes that door.

Sure, but it leaves open, say, width+: 10px. This is my point - there's still so much space open for future development. I simply do not believe there is a Future Tab who will be more than momentarily annoyed with this syntax restriction before moving to an equally-good syntax that works.

tabatkins commented 1 year ago

A problem I have with the "it's only an error recovery problem" approach, is that once something new gets added to selectors or properties, it's closed off forever in use for the other case.

Note that I explicitly addressed this case in my earlier comment, even before I started talking about the error-recovery case:

For things that are currently valid, we are indeed closing the door on options. With the current spec, we cannot allow a declaration to start with +, for example, as that's a valid relative selector. (At least, not without paying a lookahead tax that we're currently rejecting.) We cannot start a selector with an ident. As I've said in previous threads, tho, starting a declaration with a symbol is already very likely off the table, given the prevalence of people using a random ascii symbol to "comment out" a property. So in practice we're closing the door on very little new space that wasn't already verboten.

plinss commented 1 year ago

The problem is that the current proposal does not match the "common usage of nesting across more than a decade of preprocessors". It already diverges by requiring prefixes in a significant percentage of the cases.

As an example, I have a number of projects using the StencilJS framework. That framework requires scoping every custom element style rule with an element selector. The stylesheets is these projects have all sorts of repetition and would benefit greatly from nesting. Over 90% of those style rules would require prefixing in the current proposal.

I also have to point out, again, that the rules for when prefixes are necessary aren't as simple as you represent. To this date I have never seen a public-facing description of the nesting syntax that accurately describes what an ident is.

I've heard too many times to count, and even from Google implementers, that it's easier to simply prefix every nested rule.

and there's no middle ground between our two positions to make a compromise possible

And here's the elephant in the room. There is a middle ground that satisfies my objection and actually does allow the common usage of nesting. We relax the lookahead requirement. This gets rid of all required prefixes and doesn't impose any restrictions on the evolution of CSS, in fact it opens up more avenues.

The problem is that Goggle's position here so far has been "non-starter, we're not even going to consider this", with no data or explanation why. Even though other implementers have said it seems doable and are willing to experiment. I don't believe Google's position here is an example of engaging in the standards process constructively.

If there were hard data showing why adding lookahead can't be done, then we'd be in a position where we have to compromise on something else, but there isn't, and we don't.

tabatkins commented 1 year ago

The problem is that the current proposal does not match the "common usage of nesting across more than a decade of preprocessors". It already diverges by requiring prefixes in a significant percentage of the cases.

And doesn't require prefixes in the majority of cases.

The stylesheets is these projects have all sorts of repetition and would benefit greatly from nesting. Over 90% of those style rules would require prefixing in the current proposal.

So the current proposal would save you some typing in 10% of the cases versus prefixing all the time, and for most people would save them a lot more.

To this date I have never seen a public-facing description of the nesting syntax that accurately describes what an ident is.

This is because the full, accurate description of what an ident is isn't relevant to the discussion. Nobody, and I mean nobody, writes a selector like \64 iv.foo, so the fact that it's an ident (despite looking like it "starts with a symbol") doesn't matter. The ambiguous case in question is someone writing a property name (always ASCII letters, or a dash or underscore) vs a tagname selector (always starting with an ASCII letter, and usually composed of only ASCII letters).

I've heard too many times to count, and even from Google implementers, that it's easier to simply prefix every nested rule.

And we've also heard at least as many times (more times, if going by poll results) that people prefer not prefixing every single rule. The popular sentiment seems to be clearly tilted (slightly, but significantly) towards not prefixing everything.

And here's the elephant in the room. There is a middle ground that satisfies my objection and actually does allow the common usage of nesting. We relax the lookahead requirement. This gets rid of all required prefixes and doesn't impose any restrictions on the evolution of CSS, in fact it opens up more avenues.

The current spec is compatible with relaxing the lookahead requirement in the future. All it will do is make some currently-invalid CSS become valid; everything that's already valid under the current spec will remain so. The only thing that'll be encouraged to change is that selectors that would have started with an ident (and thus have to be spelled differently today) can be rewritten to be simpler, but every other selector remains exactly the same. And if those selectors aren't rewritten, well, they're still being spelled with existing valid CSS, not a legacy syntax that existed solely to fix Nesting parsing.

For every other option, relaxing the lookahead requirement in the future will mean there are now multiple ways to express any nested styles, and the previously-valid way (which presumably would remain valid) would become a legacy option that nobody uses, since it's longer. It doesn't seem great to leave behind an "oh yeah, you can put an @ before your selector in nested rules, it doesn't do anything but it's valid for some reason" legacy! (Or worse, "oh yeah, you can put an @nest in front of your parent rule, but then you have to wrap its properties in a nested rule" or "oh yeah, you can put your nested rules after the parent rule, in another {}-block, if you want", etc.)

The problem is that Google's position here so far has been "non-starter, we're not even going to consider this", with no data or explanation why. Even though other implementers have said it seems doable and are willing to experiment. I don't believe Google's position here is an example of engaging in the standards process constructively.

Steiner, personally, isn't interested in doing the perf explorations to figure out if infinite lookahead is viable. Other people are, both inside and outside of Google, and I feel confident that we'll get those explorations and see what the results are. If it turns out the way we all want, great, the current spec has the shortest path to accommodating that change, with the least amount of legacy cruft left by the wayside. If not, the current spec is the closest we can get to that syntax, and that has value to authors (as proven by their repeated votes and comments).

If there were hard data showing why adding lookahead can't be done, then we'd be in a position where we have to compromise on something else, but there isn't, and we don't.

Absent any newer experimentation, what we do have is the statements from several years ago when Nesting was first broached, where impls were pretty sure the perf hit to parsing would be too much. These positions can absolutely change over time, but we can't assume they will. I'm not willing to stake the spec's survival on something that, at last check, was a multi-implementation non-starter.

plinss commented 1 year ago

And doesn't require prefixes in the majority of cases.

[citation needed] Do you have any data to back this claim up? And it is a 90/10 majority or more like a 51/49 majority?

We do have data that shows slightly more that half the authors will simply add prefixes anyway. And for the other half allowing them to omit prefixes 50% of the time is only serving 25% of the use cases.

IMO a solution that only delivers to 25% of the use cases and has real costs to both learnability and the evolution of the language as a whole is a bad tradeoff. And even if your majority of cases is 99%, it's still not a solution for 50% of the authors.

Also, my personal prediction (based on experience) is that authors who say now that they will omit prefixes where they can will grow frustrated with the errors they encounter from forgetting them where they are needed and will shift over time into the "always prefix" camp.

The current spec is compatible with relaxing the lookahead requirement in the future

Agreed, however if it turns out we can't relax lookahead (at least for a significant amount of time), we're stuck with a solution that adds constraints to the evolution to the language.

The other solutions are also compatible with relaxed lookahead. Having multiple was to express nesting isn't harmful and some authors may simply prefer the more explicit alternatives due to clarity. Carrying the legacy syntax for a time isn't that costly.

Other people are, both inside and outside of Google, and I feel confident that we'll get those explorations and see what the results are.

Good to hear (and this is the first time I'm hearing it). So given the fact that there's a real cost to pay to for one of the solutions, doesn't it make sense to get this data before making a binding decision and shipping code? Particularly if that data may allow us to resolve all the issues and deliver a solution that makes everyone happy and covers 100% of the use cases?

I also need to point out that the push for the syntax decision isn't being phrased as "We're really going to try to relax lookahead and just deliver the SASS syntax, but that's going to take time, and we want to ship an interim solution in the meanwhile". If that were the case, it changes the dynamics of the equation. Because frankly, I've been waiting 25 years for nesting, and if it means I have to wait another 6 months for a real chance to get a good implementation, I'd rather wait. If we know for a fact that the better way of doing can't be done at all, or maybe not for another decade or so, then the push for delivering something makes more sense.

tabatkins commented 1 year ago

[citation needed] Do you have any data to back this claim up? And it is a 90/10 majority or more like a 51/49 majority?

Most selectors in the wild are based on classes, pseudo-classes, or attributes, just as a rule. Element selectors are a minority in complex selectors. And to be problematic for our purposes, the element selector has to be part of the first compound selector in the nested rule's selector, and the nested selector has to be either non-relative, or relative with an implicit descendant combinator.

For confirmation you can just go look at the CSS from a random collection of popular websites.

So given the fact that there's a real cost to pay to for one of the solutions, doesn't it make sense to get this data before making a binding decision and shipping code? Particularly if that data may allow us to resolve all the issues and deliver a solution that makes everyone happy and covers 100% of the use cases?

There is a cost to pay for all syntax options. In a significant way, the major decision is whether we're pushing the cost to all authors (requiring a more verbose syntax) or to future spec authors (requiring more careful syntax design in the future). As I've argued, I think the latter cost is actually extraordinarily small in practice.

If we know for a fact that the better way of doing can't be done at all, or maybe not for another decade or so, then the push for delivering something makes more sense.

Again, the current spec is pretty trivially switchable into an unlimited-lookahead syntax. All other approaches require us to be left with a legacy syntax in addition to the unlimited-lookahead syntax. So if we want to ship something ahead of confirmation (or denial) that unlimited-lookahead is viable, the current spec is still the best way to do so.

LeaVerou commented 1 year ago

@tabatkins You mentioned that other folks at Google are looking into this. Is this exploration happening somewhere in the open? If so, could you point us to any of the relevant issues? I’m very interested in the specifics, and I suspect others may be as well (and who knows, might even be able to provide input — lots of smart folks here). Thanks!

tabatkins commented 1 year ago

Nobody has started on it yet, there's just been discussion.

FremyCompany commented 1 year ago

One question I would like to add before today's meeting: can we at least make the current draft a lookahead of 1?

The proposal would be as follow: to be considered a property declaration, the current token sequence should start with an identifier immediately followed by a colon (notwithstanding whitespace).

This would allow to drop the & in many more cases where selectors start with a tag name (which unlike what some seem to argue, is very common). It would however break for selectors like a:hover but I think this is reasonably easy to explain to developers, and also will be visibly different in syntax highlighting, making it directly clear what the error is (even without explanation).

This will reduce the burden while converting stylesheets to nested rules quite a lot, and would reduce the "syntactic disadvantage" given to tag selectors in CSS.

If, at a later date, implementors want to pursue further lookahead relaxation, this is still possible, but at least, we already start by enforcing some.

Loirooriol commented 1 year ago

A Google search for "CSS star hack" returns 9.8 million results.

@jensimmons That may be the case for *, but the claim did cover several other symbols like +. I'm not aware of + being frequently prepended to declarations, and I'm still not seeing any data showing that.

It would however break for selectors like a:hover

@FremyCompany I'm afraid this would just cause further confusion, and authors would rightly complain about the CSS design making no sense.

This will reduce the burden while converting stylesheets to nested rules quite a lot

Why should this be a goal at all? Existing stylesheets can stay as-is.

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed [css-nesting] Problem with mixing properties and selectors.

The full IRC log of that discussion <JakeA> oh a link is even more handy :D
<argyle> astearns: peter do you want to summarize and start
<argyle> plinss: i have several concerns, most are aware of them, we can review what we need to
<argyle> plinss: my best path forward is relax and do the sass syntax and require prefix nowhere. we need to explore that
<argyle> plinss: we should take some time to experiment if a path is feasable, especially controversial. make all authors happy if we give them this syntax
<TabAtkins> q+
<argyle> plinss: we have soemthing that hasnt been considered or discussed, i'm asking we do that first
<argyle> astearns: we experiment, get some data, is feasible is performant enough
<fantasai> s/especially controversial/especially because it's controversial/
<argyle> plinss: we added this restriction 25 years ago, and i wasnt convinced we needed it back then
<Rossen_> q?
<argyle> plinss: since then, i dont think anyone has pushed back and challenged it. there's some experience fromt he tag that's done extra look ahead, said it wasnt a big deal. lea and i have discussed strategies, doesnst require entire parser changes. could be a small change. why arent we exploring this?
<dbaron> This was explored a bit in https://github.com/w3c/csswg-drafts/issues/7961
<astearns> ack TabAtkins
<argyle> TabAtkins: as ive said in the thrads a few times, the current proposal is the most ameniable to look ahead in the future
<fantasai> s/fromt he tag/from a developer/
<argyle> TabAtkins: in t he future, it would just b e removal of some restrictions
<fantasai> s/lea and i/TAG and Lea and I/
<fantasai> s/thrads/threads/
<plinss> q+
<argyle> TabAtkins: we could walk or drop back to achieve this. 2 ways forward, restrictive at first
<argyle> if we go with any other solution and later upgrade look aheda, we'll have ways of writing. wierd way and correct way.
<argyle> if we go with the current proposal and then look ahead, then delta is small. might see an is() selector wrapped around a typue selector. but the rest will be identical. smallest delta one to the other
<fantasai> s/if we/TabAtkins: if we/
<fantasai> s/if we/TabAtkins: if we/
<fantasai> s/is()/:is()/
<argyle> TabAtkins: about investigating infinite lookahead. this isnt a 25yr old restriction. folks looked into it about a decade ago when i was first looking into parsing.
<futhark> q+
<argyle> TabAtkins: at that point, there wasnt a serious exploration. but implementors did believe it would be too much of a cost in a hot area, in initial page css parsing. we've been wrong, and i'd be delighted to be proven wrong (like has)
<argyle> TabAtkins: until we do, i dont want to, or think we should block progress under the assumption that advacnes in stuff have solved our perf issues. sometimes it does or doesnt, in the meantime folks are clamoring for it
<argyle> TabAtkins: sorry y'all community, we'll continue to push it away for N months
<argyle> TabAtkins: any case, we go with the current proposal or infinite lookahead. the current proposal is still the best solution int he absence of lookahead
<JonathanNeal> When we talk about Sass style nesting, I think it’s important we distinguish which features of Sass style nesting we would be copying.
<argyle> TabAtkins: either way, we end up in the same world. either a slight shift towards infinite lookahead, or we wait and get the full syntax.
<JonathanNeal> For example, in CSS style nesting, tokens would be independent parts of a selector, whereas in Sass I think tokens can concatenate into new kinds of selectors.
<lea> JonathanNeal: The ones that don't involve concatenating within tokens :)
<argyle> astearns: we not talking about "infiniite" lookahead, as i understand. and i'm hoping it's not months. just quick data to inform what we're doing, instead of just not answering the question
<fantasai> lea, I think not concatenating within tokens is totally reasonable and understandable. I think the way that we wrap things in :is() is going to trip people up, though
<argyle> TabAtkins: it is infinite lookahead, because you can have unlimited ambiguous lookahead
<astearns> ack plinss
<lea> q?
<argyle> plinss: again we're not discussing how long it will really take to do this. i dont believe it's months. it oculd be days or weeks.
<argyle> plinss: if we do this experience, one of3 outcomes: prove lookahead is not viable and never will be. or we discover it'll take more time and it will take months.
<fantasai> lea, like "article { section h3 { ... } }", it can map to "section article h3" and that's not generally expected
<lea> q+
<TabAtkins> (fantasai, i think you mean `article h3 { section & {...}}`
<TabAtkins> )
<argyle> plinss: in the situation where we prove it's not viable, i'm still not convinced what we have is the best answer. but i dont want to debate it. i will argue that any approach that requires a prefix, is also something we can relax in the future if we figure out lookahead. once we make prefix optional, we can never go backwards if we make a mistake. if we start witha prefix, we can always relax it
<jensimmons> q+
<argyle> plinss: so that is the safer approach. again, i dont want to tangent until we determine is the experiment viable
<argyle> if it's weeks, lets wait a few weeks
<lea> fantasai: yup, that's a separate issue on the agenda, right?
<argyle> plinss: i've been waiting for nesting for 25 years, but if we say give me another month or two and we can give you everythign you really want, folks would be ok with that
<astearns> ack futhark
<TabAtkins> q+
<argyle> futhark: about the details and implementation in blink. we have something we call a streaming parser, we throw tokens away as often as possible. we used to tokenize the whole stylesheet until the parser took over, we had some peek memories
<argyle> futhark: being able to throw away tokens helps us with memory
<fantasai> s/peak memories/high peak memory usage/
<plinss> q+
<argyle> futhark: for us we'll know the problems with infinite lookahead, we'll need to go back to something similar we had before
<argyle> futhark: another issue is, the block stack doesnt need a snapshot in order to restart the parsing for a property
<argyle> futhark: i dont think it's a matter of days, in chrome, it's definitely weeks at least
<argyle> plinss: first of all, yes it's theoretically infinite look ahead, the average will be small. not a cost you pay all the time
<argyle> plinss: only cost with obscenely long selectors
<argyle> plinss: this is an experiement. you dont have to make production code, you can quick hack and try it out
<argyle> plinss: you dont have to worry about a block, you have lookahead, you're parsing a property or declaration, if you see a token that's not an ident, youre done. if there is one, lookahead and move on. if it is a colon, lookahead until you see another sigil. if you see an open brace first, you see a rule, move on. not a huge deal.
<argyle> plinss: may take months to perfect, but an experiement could take hours or days
<lea> (fyi the algorithm plinss is describing is what I proposed in #7961)
<astearns> ack JonathanNeal
<oriol> Note custom properties can contain {
<argyle> JonathanNeal: ty lea what i'm going to bring up in the chat already
<lea> q?
<argyle> JonathanNeal: i wanted to share, terms like "everything developers want", is hard for me. i assume we're talking about nesting from Sass? the reason i'm having trouble is that sass is concat based, which i presumed is off the table. therefore i'd edpect that a goal of acheiving parity, would be mute if they would still have such fundemental differences. dont mean this to disuade research, but as far as parity, i thought it'd be mute without
<argyle> concatenation. .
<fantasai> s/mute/moot/
<fantasai> s/mute/moot/
<argyle> plinss: for clarity, i mean not requiring prefixing, not necessarily the other features. separate discussiont o follow it 100%
<astearns> ack lea
<argyle> lea: to reply to jonathan first, the sass folks admitted concat was a mistake. we mean & always being optional for descendants. if there's a better name, happy to use it.
<argyle> lea: reason i'm on the queue, if we assume infinite lookahead is possible, how could we decide around this unknown.
<argyle> lea: one thing we could decide on, assuming lookahead is not possible, do we still want option 3. if so, adopt 3 now nd lookahead in the future.
<argyle> lea: if option 3 depends on lookahead, then sure we can wait like peter said
<lea> argyle: If lookahead is NOT possible, do we still need Option 3? Then we can adopt it now. If lookahead *is* possible, do we want to adopt the additional restriction that braces cannot be included anywhere in the value of a property? (we can still allow the entire value to be enclosed in braces, for mixins etc, and braces in strings are not a problem). If we *don't*, then the whole exploration is moot.
<fantasai> s/argyle/lea/
<argyle> lea: 2nd, if it is possible, it doesnt automatically solve the problem. we can make & optional. lea just pasted it
<JonathanNeal> I write things down in advance, too. And I still fumble every time. :)
<argyle> lea: in issue 7961, it was also pointed out that ot adopt this, even with infinite lookahead, we need to forbid braces in custom properties
<argyle> lea: we could allow braces to wrap the whole value, so future can do mixins and shortcuts, some syntaxes that require that. still possible, can't have empty pseudo class, no conflict there. we do need to forbid braces in the property value
<argyle> lea: looks like these are fairly uncommon, but would restrict some cases
<Rossen_> q?
<argyle> lea: i think the tradeoff is worth, would be good to have a resolution on this. if we know it's possibnle, we we lift the restriction
<argyle> TabAtkins: i'm writing the rules of thing we'd run into while we do these minites
<argyle> lea: would be nice if the issue was updated
<bramus> Don’t people drop JSON in custom props? I know I’ve done before 🙈
<fantasai> s/while we do these minites/I'll paste it in a few minutes/
<astearns> ack jensimmons
<plinss> q-
<argyle> jensimmons: this question about lookehad is really important, i appreciate the WG is finding out if this is possible. here at apple we've been talking about it alot
<argyle> jensimmons: this idea its easy and is only a couple hours, is honestly kinda insulting. it's nto easy, it will take weeks
<argyle> jensimmons: a hacky quick, yeah of course, we can of course do that, the quetion is, at what perforamnce cost?
<argyle> jensimmons: a quick hacky edperiement doesnt answer that questoin, a deeper dive is required to see the impact
<lea> everyone values performance, no?
<argyle> jensimmons: i can tell you the webkit team, we value perf incredibly highly. its not simple to "just toss it is, no big deal". it will take time
<JonathanNeal> Would anyone know — does the GitHub issue already address selectors like `color-scheme:nth-child`...?
<plinss> q+
<argyle> jensimmons: we wont know how long that effor takes until we have an answer
<fantasai> JonathanNeal, yes
<argyle> jensimmons: or we keep going and the perf is trash, until we decide it's not viable
<JonathanNeal> fantasai: thank you
<bramus> q+
<fantasai> JonathanNeal, that's the problem, fundamentally -- the overlap in syntax between selectors and property declarations
<lea> q?
<argyle> jensimmons: it's not a quick thing. also, engineers dont live in isolation, there's a schedule. it's always a balance, cant just clear the desk and work on lookahead. please undersatnd we value and care about and determine if this is possible. is it going to happen nexxt week, or next 3 months, no.
<argyle> jensimmons: we have a implementations and a spec, we have an option 3 soltion that web developers are thrilled about
<JonathanNeal> fantasai: Yes. I was under a (potentially false) presumption that this fundamental issue has been researched and discussed many times over recent years during the acceptance of the original CSS nesting proposal.
<TabAtkins> Here's the proposed parsing: https://gist.github.com/tabatkins/6c230f0ce612d80979e4a4bdfa7ee489
<argyle> jensimmons: even tho there's a gotcha, which i did not like at the beginning, is clear at this point there is broad consensus we like to ship option 3 with this gotcha. in the future we'll dive into if or when, if not in the next year then 5 or 10 years, we can change and evovle nesting
<argyle> plinss: a, i'm not trying to be insulting, but my point with a quick hack, i'm not proposing we ship the quick hack, just a quick hack for data. if it's not optimal, but it turns out to not be that slow, we have our answer now without waiting
<argyle> plinss: 2nd, we've aalready settled on option 3, we havent, i'm an objection. we got to that point by widdling down options.
<argyle> plinss: new information came to light, and if we had that all along we would have made different decisions. it will lead to a formal object if we want to ship option 3 today. that isnt a quick fix here
<JonathanNeal> TabAtkins: As a user-land polyfiller, I both respect that comments are thrown out before these rules in the parser spec, and yet it still makes reading parser rules just harder enough. :P
<argyle> jensimmons: regarding perf, it might happen that way peter. might discover some feedback and path of where it's going to go based on early results. it often doesnt fall together than neatly. we might get lucky and it only takes a short time, that's hoping, that's not how eng schedules are made.
<argyle> jensimmons: 2, i did not say we settled, i said we have broad consensus.
<emilio> I volunteer to explore the nesting w/ unlimited lookahead in Gecko in the next month, fwiw
<lea> q+
<argyle> plinss: my point with the experiement, scheduling concerns, etc, i think if its this high priority, we want to get this thing settled. an eng couldl take a day or 2 to figure it out, and if the worst case is acceptable, we know our path forward. even if it takes a week or 2, it's worth waiting. and we dont have to wait on apple, anyone testing can find the answer.
<argyle> plinss: at least we tried to settle it quickly, and i dont think that's unreasonable
<astearns> ack TabAtkins
<emilio> q+
<plinss> q-
<plinss> q+
<JonathanNeal> Re: "Non-custom properties can never contain top-level {}-blocks". Pouring one out for Custom Property Sets.
<argyle> TabAtkins: the big procedurral thing here, in terms of ordering. if we assume, like we wait for dataon this, and we find infinite lookahead is fine, we switch to that. if not, peter asusmption seems to be that we wouuld go back to discussing all options again. but before this, we researched under the assumption that infinite lookahead is not feasible, unless there is new information that we would make a new decision from option 3 and months of
<argyle> discussion, we should work under the assummption we'll make the sasme decision
<argyle> TabAtkins: either now, infinite lookahead or current spec. reminder, we can convert option 3 to infinite lookahead
<argyle> TabAtkins: i dont think we're going to throw away consensus we've acquired so far
<argyle> TabAtkins: if we find no lookahead and we want option 3, peter will still object. whether that's not or after exploration, we can do that now
<argyle> astearns: i disagree that waiting and finding that infinite lookup isnt feasible, means we start over. we've been assuming it's not possible, so we'll likely end up with option 3 if we find it's not feasible. but, if it is feasible, the design could radically change.
<argyle> astearns: we'd be better off with a single good solution than a design based on the assumption wasnt feasible, then switching to it is. i think it's a bad thing to go with a solution based on unproven assumptions, then change things later
<jensimmons> I agree with Tab that we've already figured out what we want to do without lookahead.
<JonathanNeal> I think denying top-level blocks to declarations feels harsh to me.
<argyle> TabAtkins: i agree, the current spec has no author visible changes if we go with infinite lookahead
<fantasai> s/lookahead/lookahead, other than allowing selectors to start with a tag selector/
<JonathanNeal> But I admit it’s never really been tested. There is nothing like an `aria: { selected: true }` shorthand declaration.
<jensimmons> And I believe we do know what we want to do if lookahead if possible — that we would do Option 3 without the 'gotcha' of requiring an `&` before an element selector
<argyle> plinss: i'm not saying we reopen every issue, but it's unfair to not look at all issues because we didnt look at all the information. alot of decisions were made of syntax convenience or capability, not the fact it closes off design space in the langauge. we do need to reconsider some of those option sin that light.
<argyle> plinss: if we're going to go there, it's a bigger decision. we dont have to go there if lookahead is feasible
<TabAtkins> That is 100% wrong, we considered the language-evolution concerns all thruout.
<Rossen_> q?
<argyle> plinss: jen was saying, all the authors are thrilled with 3, we have data that many authors will put the prefix there anyway. optional prefix serves a fraction of the users. i see it as a footgun. if they try and do it without it, they'll waste time looking for the bug. it's not really that great a solution
<argyle> plinss: we dont have to have this debate, if infinite lookahead is feasible
<astearns> ack fantasai
<Zakim> fantasai, you wanted to respond to peter
<JonathanNeal> In my limited circles, automatically prefixing everything felt a bit like making a strong formatting decision about the use of semicolons or braces in JavaScript.
<argyle> fantasai: peter is arguijng that the conerns about forward compat will chagne everything, i strongly disagree with that. the usability concerns are very real, main reason i dont like optoin 3. we did discuss those at length, and we landed at optoin 3 anyway. which i have to accept that's where we are at.
<fantasai> https://github.com/w3c/csswg-drafts/issues/8249#issuecomment-1362033982
<argyle> fantasai: the css language cutoff is very small, we're not causing any future problems. i dont see a real problem with future compat
<argyle> fantasai: i dont think that bringing up future compat into the discussion with higher consideration is going to cause any change in our decision. the biggest problem is the usability concern, and we've already discussed it with our eyes open
<bramus> q-
<astearns> ack bramus
<astearns> ack lea
<argyle> lea: option 3 was a compromise because we assumed lookhead was not possible. if lookhead was possible, it might be better to ship a syntax where & is mandatory everywhere, so later it can be optional everywhere
<argyle> lea: do not this doesnt fix all the lookahead issues
<JonathanNeal> appreciate that comment, fantasai, and strongly agreed as someone who has worked with/on multiple user-land parsers.
<argyle> lea: makes more sense to be mandatyory at first, later not. instead of it's kinda mandatory, not it's totally optional
<bramus> Would be difficult to feature detect, no?
<argyle> lea: seems like a more reasonable progressions. i could still stand by 3 if lookaheda is not possible
<argyle> lea: but if lookahead is somewhre down the line, i'd prefer this kind of progression
<argyle> TabAtkins: required the & doesnt fix infinite lookahead
<argyle> TabAtkins: we can't make it mandatory. that means parsing requires looking in the future we is the exact thing we're discussing.
<argyle> lea: we can make it mandatory in addition to option 3
<argyle> lea: & mandatory with all descendants
<jensimmons> I don't think that's easier for devs — to have & .foo and :is(article) & ... that's confusing
<JonathanNeal> This break is brought to you by Coffee and Cheetos.
<lea> argyle: If we *knew* that lookeahead is possible and it would just take a while to implement, I think it would actually be better to ship an even more restricted variation of Option 3 with an always mandatory ampersand; then it can be made optional everywhere at once. (Do note that making the & mandatory doesn't actually remove the need for the other parsing rules wrt non-idents, since the & can appear later in the selector)
<fantasai> s/argyle/lea/
<argyle> plinss: how long will it really take to test lookahead? still feels unanswered
<argyle> TabAtkins: it'll likely be months, but we do have someone for Q2 or Q3.
<astearns> ack emilio
<emilio> oh, no mic
<emilio> sigh
<plinss> q-
<Rossen_> q+
<Rossen_> q-
<bramus> q+
<emilio> Anyways, I was going to say that I can explore this in the coming months or so
<Rossen_> q+
<astearns> ack Rossen_
<emilio> I can set some time aside for this
<argyle> emilio: Rossen_ i was interested to hear more about, and observing, listtening. sounds to mem like peter is asking can we have functional verification it's possible. on the back of it, can we validate this is feasible from a perf pov. having worked for perf in various browsers, it's all speculation until tried. speculating it's bad or good is just a speculation
<argyle> Rossen_: it doesnt sound like having option 3, even if we ship today, doesnt preclude anyone from having infinite lookahead option, which will sipmly relax the restrictions. we have 2 options forward
<argyle> Rossen_: i dont hear them as exclsuive. having one of the lookahead will make option 3 mute, but if we're looking at this, sounds like opt 3 is leaning towards.
<fantasai> s/mute/moot/
<argyle> Rossen_: main issue is, can we have functional validation, then have someone validate and run it through labs and get a good picture. not weeks or months. then yo ucan figure out if you can put htis into production
<astearns> ack emilio
<argyle> emilio: i can set some time aside and try infinite lookahead this month or so? that useful?
<argyle> astearns: yea i think so
<argyle> astearns: that would be a timeline folks would respond well to
<plinss> q+
<argyle> astearns: personally, it'd b e better if we had some experiementation in lookhead before we go ahead and ship, but that's my preference
<jensimmons> q+
<Rossen_> +1 to having look-ahead eval before option 3 go-live
<argyle> astearns: if we ship without the info, i'd want a clear path for if we see it's feasible, how does the nesting story change. how do we go from option 3 to better syntax with infinite lookahead. not cleaer to me what the transformation is like and what the authoring dissonance would be in having both
<JonathanNeal> Are we presuming or not presuming TabAtkins’ proposed parsing restrictions for infinite look-head? I would think the restrictions may make it disqualifying, separate from capability or performance.
<astearns> ack bramus
<matthieudubet> should we define what is "acceptable" for performance regarding unbounded lookahead (1% perf regression on speedometer?)
<TabAtkins> JonathanNeal, not sure what you mean
<argyle> bramus: one side of the story, yes infinite lookahead not quick to try out and the other is option 3 than there's going to be an objection. at a stand still? how to unblock?
<JonathanNeal> I am referring to “Non-custom properties can never contain top-level {}-blocks”, TabAtkins.
<argyle> bramus: my idea is to be a minimal version of option 3. it'd look like, & is required and only allowed at the start. then if lookahead is viable, we upgrade to sass like, if not it can move into option 3 as it is today
<argyle> bramus: that minimal version can relax to either
<argyle> bramus: to peters concern, with mixing props and selectors, and that only prevents the & from being the first character of th eproperty, that's reserved
<argyle> astearns: confirm that useful
<JonathanNeal> To me, restricting 1/3 of the recognized grouping syntaxes would put a significant restriction on future combat.
<astearns> ack plinss
<astearns> zakim, close queue
<Zakim> ok, astearns, the speaker queue is closed
<Rossen_> rossen: ... also, don't forget that this needs to go into all parsers, not just the ones controlled by the browser engines (i.e. the best engineering staffed teams)
<argyle> plinss: clarify my position, if someone does the research in a short amount of time, but it'll be 6 months to solving fully. then i'm ok knowing we ship option 3 now because i know the future pain will go away
<argyle> plinss: if the response is, it's going to take 6 months to have an asnwer at all, and we want to ship in the meantime, i'm not going to object a mandatory prefix. lookahead viability determines amuch safer option
<astearns> ack jensimmons
<argyle> jensimmons: processing what peter just said
<argyle> jensimmons: peter, if you've got a commmitment from a browser team or mnultiple to serioulsy look at lookahead in the nexxt months, you'd be ok shipping option 3 as it is now knowing we relax it if possible
<argyle> plinss: if we dont know if it's feasible or not. if we find it is, but it's going to take time, then i'm fine with option 3
<florian> q?
<florian> q+
<argyle> plinss: if we dont know, ship with a required prefix. thenwe can research and discuss relaxing in some situations, or if it's feasible we relax it in all situations
<Rossen_> q+ for before end of call and start of next call
<argyle> plinss: if you really want to ship something today, that works. or we awit for emilio
<argyle> jensimmons: but a few weeks is um, i wish you'd said this a month ago
<argyle> jensimmons: w3c process document, it's clear that says we have an otpoin to take a vote. only if chairs need it to break a dead lock.
<argyle> astearns: as chair, i dont think we're at that point. we have a volunteer to get the information, which is what peter is asking for, i dont see a reason to resolve today
<argyle> TabAtkins: if we dont make a resolution, we're not going to wait more months. the clock has run out
<argyle> astearns: we've taken shortcuts on this to get something done quickly, and i dont think it's unreasonable to wait a few more weeks for more information
<argyle> TabAtkins: it's not going to be a few weeks.
<argyle> emilio: i'm saying i can look into this in the next month
<argyle> emilio: not 6 months. i want nesting to be as good as possible
<argyle> TabAtkins: point is, in the absence of lookahead, the group decides on option 3
<dbaron> Are we going to have another breakout at the same time next week? (I also think it would be useful to prioritize #8310, since I think it also may be a blocking issue for the entire spec... and it's an entirely different (non-parsing) issue.)
<argyle> TabAtkins: if it's impossible, that decision stands unless we have a good reason to change it
<argyle> TabAtkins: i dont think we should spin our wheels on otpoins
<argyle> emilio: can we confirm lookahead is possible or impossible before chosing option 3
<argyle> jensimmons: i'm excited you can take time to look at it in the next month
<argyle> jensimmons: do agree with tab, it doesnt make difference on option 3 in the meanwhile
<argyle> jensimmons: he's fine with 3 in the meanwhile, and if we believe lookahead is not possible, i agree with tab we're going to resolve the same way we already have
<Rossen_> q?
<florian> +1 to jensimmons and TabAtkins
<JonathanNeal> it’s just me :)
<argyle> jensimmons: we've debated & requirements and we've decided no. why cant we ship 3 without a clear answer to infinite lookahead
<argyle> plinss: why is a few more weeks so impossible? we've already waited 25 years
<argyle> JonathanNeal: regarding the research of lookahead, i believe multiple sources have researched that there'd be separate restrictions. separate from possible or performant but it'd be a significant restriciton if grouping needed changed.
<argyle> JonathanNeal: why cant we move forward with both?
<argyle> plinss: current syntax hinders the css language. not a zero sum game, retrictions here vs restrictions there
<JonathanNeal> Thank you, everyone, for allowing me to participate.
<argyle> jonathan, help me fill yoru comments, i lost a bit of it..
<dbaron> astearns: I will propose another breakout at the same time next week.
astearns commented 1 year ago

One of the claims I have heard is that we can ship option 3 now, then in a lookahead future we can update nesting syntax. Could someone elaborate on what that update would look like?

I am also interested in exploring the suggestion from @bramus about shipping a subset of option 3 with a required & to start, then gradually adding more functionality over time. That seems like a promising compromise, though it would likely make the @supports story much more complicated

plinss commented 1 year ago

To be clear, my objection comes from shipping option 3 without knowing if we can relax the lookahead restriction or not. Because if we can't, it carries the syntax restrictions, is an author foot-gun, and only satisfies significantly less than 50% of the use cases (vs a mandatory prefix). I don't feel the benefits outweigh the costs. If we covered 100% of the use cases then the math might work and it'd be worth it, but we're not there.

I'm fine with shipping a solution (like @bramus's suggestion) where a prefix is required for now, and we can make the prefix optional in the future if lookahead proves viable, or we can decide to make it optional in some cases later if lookahead proves to be impossible (essentially morphing it into option 3 or some flavor with limited lookahead and more options to omit the prefix).

I'm also fine with shipping option 3 as-is, as soon as we know for a fact that look-ahead is viable, as an interim step until full lookahead can be implemented, because all the down-sides are temporary. (I personally don't think it would be worth shipping, but I wouldn't object to it.)

Every solution so far is compatible with adding lookahead later and simplifying the syntax. And frankly, even if/when full lookahead ships, it might still be beneficial to also have an optional prefixed syntax for authors who want to make their stylesheets more clear (though I wouldn't be bothered if we didn't).

LeaVerou commented 1 year ago

I am also interested in exploring the suggestion from @bramus about shipping a subset of option 3 with a required & to start, then gradually adding more functionality over time. That seems like a promising compromise, though it would likely make the @supports story much more complicated

I think you may be referring to the point I made: that if we know infinite lookahead is coming, I'd rather ship a syntax with a mandatory &, so that it becomes optional for descendants and combinators at once. Note that I'm only proposing this for user experience, it does not solve the lookahead issue to have a mandatory &.

Note that I only think this is a good idea if we know that infinite lookahead is possible. If not, I think Option 3 as it currently stands is a better bet.

astearns commented 1 year ago

@LeaVerou I was thinking of the addition to your suggestion that we have a mandatory & and only allow the nesting forms that begin with & until we determine whether lookahead is possible.

tabatkins commented 1 year ago

One of the claims I have heard is that we can ship option 3 now, then in a lookahead future we can update nesting syntax. Could someone elaborate on what that update would look like?

For authors, the update looks like "you don't need to worry about selectors starting with an ident anymore, it Just Works™ (but if you were already doing :is(div).foo that's still fine)".

For implementations, we're working thru what the parsing algo would look like in https://github.com/w3c/csswg-drafts/issues/7961#issuecomment-1396112293

I think you may be referring to the point I made: that if we know infinite lookahead is coming, I'd rather ship a syntax with a mandatory &, so that it becomes optional for descendants and combinators at once. Note that I'm only proposing this for user experience, it does not solve the lookahead issue to have a mandatory &.

I'm strongly against a "mandatory &" - nothing is helped by requiring an & somewhere. (That is, div > & satisfies this but is still problematic in such a world, while > div has no problems but is mysteriously disallowed by such a restriction.) I don't understand where this suggestion is coming from or in what way it would help us.

and only allow the nesting forms that begin with & until we determine whether lookahead is possible.

This is also overly restrictive. Again, if we determine infinite lookahead is possible, then div + & is fine. If we determine that it's not possible, then the WG has already spent months talking over all the options, and decided the current spec is the most preferable way forward.

The only reason it would make sense to impose such a restriction is we think that, when we determine that lookahead is infeasible, we'll scrap all the preceding resolutions and re-evaluate the entire issue fresh. But we're not going to! All of the discussions we've already had were made under the assumption that infinite lookahead wasn't possible, so if we decide that it is, indeed, not possible, we'll just be affirming that the preceding discussions were assuming correctly.

The only effect that our investigation into infinite lookahead can have is proving that is is possible, and causing us to switch over to a parsing method with the new assumptions. Otherwise, our current situation is unchanged, and we should stick our current resolutions.

astearns commented 1 year ago

Here is my reasoning, which is not based on scrapping anything.

A. Start by allowing nesting forms with a mandatory leading & (so that people have something to ship now) B. Keep investigating lookahead C1. If lookahead is feasible, never do the :is() thing. When a UA can do lookahead, then they can ship the rest of nesting (and make & optional where possible) C2. If lookahead is not feasible, UAs can ship the rest of option 3

tabatkins commented 1 year ago

Right - how does that help authors? Either infinite lookahead is feasible, in which case they can write div & (or :is(div) &, tho they wouldn't), or it's not feasible, in which case they can write :is(div) &. Disallowing them from writing either (and disallowing them from writing .foo &, which they'd be able to do in either case) until we figure out which case it'll be doesn't seem to help anyone.

astearns commented 1 year ago

If it’s possible to avoid the :is(div) & form entirely, I think that’s a win for authors. My preference would be to hold up shipping anything until we thoroughly investigate lookahead, but I expect some sort of compromise may be needed.

plinss commented 1 year ago

I'm strongly against a "mandatory &" - nothing is helped by requiring an & somewhere. (That is, div > & satisfies this but is still problematic in such a world, while > div has no problems but is mysteriously disallowed by such a restriction.) I don't understand where this suggestion is coming from or in what way it would help us.

I'm against that as well, but that's not what's being proposed here.

The only reason it would make sense to impose such a restriction is we think that, when we determine that lookahead is infeasible, we'll scrap all the preceding resolutions and re-evaluate the entire issue fresh. But we're not going to!

1) 'we're not going to!' isn't your call, that's the chairs' call, and other group members are well within their rights to ask that these decisions be revisited. 2) while all the previous decisions were made with the assumption that lookahead wasn't possible, they didn't take into account all the pitfalls of the solutions at the time. Yes Tab, I'm aware that you said that you did, and I accept that, I also accept that others involved in coming up with the solutions that led to the current option 3 syntax did as well, however those pitfalls were absolutely not part of the discussions with the whole group when the resolutions were made[1]. They also weren't mentioned in the public polls. So yeah, if lookahead isn't possible, we do need to revisit at least some of the previous decisions given the new information. If lookahead is doable, then that's all moot and there's no point revisiting those. Given the degree of contention, and emotions running high, it might be best to avoid going there if we can by simply waiting a few weeks for the lookahead investigation.

If it's determined that the lookahead research is going to take longer than people are willing to wait (which has not been determined yet), then shipping a partial solution that always requires some kind of prefix is the safest bet. Because if we determine that lookahead can't work, and if we revisit the prior decisions and decide that an optional prefix isn't actually the best path forward after all, then we haven't painted ourselves into a corner by shipping something prematurely. We can always make at least some of the mandatory prefixes optional, but we can never make optional prefixes mandatory without breaking content.

I also have yet to see any justification as to why this needs to be rushed. If there's a real need to push a solution out the door ASAP, then there should be justification for prioritizing the lookahead research work.

[1] for example, when I mentioned some of the language evolution tradeoffs, people were surprised.

bradkemper commented 1 year ago

If it’s possible to avoid the :is(div) & form entirely, I think that’s a win for authors.

I have a hard time imagining how that would be a win. Even if :is(div) & is cumbersome, it is better than not being able to express that at all, by requiring the selector to begin with a &.

plinss commented 1 year ago

If it’s possible to avoid the :is(div) & form entirely, I think that’s a win for authors. I have a hard time imagining how that would be a win. Even if :is(div) & is cumbersome, it is better than not being able to express that at all, by requiring the selector to begin with a &.

With lookahead that would simply be div &, which is the win we're talking about. What @astearns is describing is a proposal where even :is(div) & wouldn't be valid in V1, only selectors that begin with a & (and have no other & anywhere). Once we know if lookahead is viable or not, we either make div & valid (and any other selector without a &, leading or not) or :is(div) & depending on the outcome.

bramus commented 1 year ago

@tabatkins The slimmed down option 3 – with required leading & - was proposed during the call to break the standstill we were in:

  1. Option 3 – which was already chosen as the winner before and was as good as ready to ship – only needed the final stamp of approval.
  2. Giving option 3 the stamp of approval would have resulted in a formal objection because we lacked data about a relaxed/infinite lookahead being viable or not.

With that slimmed down option 3, vendors could ship at least “something” (which could still be upgraded to the full Option 3) while also preventing the formal objection from happening. It also worked around other discussions that were still ongoing at the time (e.g. “How would it desugar?”).

Would this have been ideal to authors? Probably not, but at least it would have allowed them to cover only the basic cases.

But the entire suggestion is no longer valid I think, as @emilio offered a better escape hatch to the standstill by looking into the viability of infinite lookahead. As detailed in https://github.com/w3c/csswg-drafts/issues/8249#issuecomment-1396198517 by @plinss that research won’t prevent Option 3 from shipping. Correct me if I’m misunderstanding Peter, but it would boil down to:

So yeah, Option 3 is the version that’s still on the table and the one that will go out the door. Maybe it’ll even get an extra upgrade before it does.

tabatkins commented 1 year ago

I'm against that as well, but that's not what's being proposed here.

It was, by Lea, and I said that in a response quoting them.

If it's determined that the lookahead research is going to take longer than people are willing to wait (which has not been determined yet), then shipping a partial solution that always requires some kind of prefix is the safest bet.

The timing of the research has no bearing on what we do in the "infinite lookahead is infeasible" case; this is a non sequitur. The only way in which it can be relevant is if we start by intentionally limiting the current spec to the intersection of "infinite lookahead is fine" and "infinite lookahead is not fine". I don't think we should do so (as I said in response to Alan), but if we did, a required prefix is already out of that intersection.

The only reason to use a prefix now is if we are planning to revisit the last year of discussion, and think that a particular prefix syntax has a good chance of being the final resolution. Absent that, any prefix is just as uncertain/unsafe as any other syntax.

I also have yet to see any justification as to why this needs to be rushed.

"It doesn't need to be rushed" and "it doesn't need to be further delayed to revisit previous decisions, after more than a year of active discussion" are different things. If evidence of infinite-lookahead viability would cause us to present a different author-facing syntax, that would be a different story, but it won't.

Since the current syntax is compatible with either result of the lookahead research, the only reason to continue to delay shipping at this point would be if we thought we were going to overturn our existing consensus. Whether we do so or not has nothing to do with the lookahead research, however.

tabatkins commented 1 year ago

The slimmed down option 3 – with required leading & - was proposed during the call to break the standstill we were in:

I know, but again, that wasn't what Lea was referring to, either here or in the call. They explicitly said they were talking about requiring a mandatory & somewhere in the selector, separate from whatever we do for the prop/rule disambiguation. (This sort of restriction has been talked about in previous discussions.)

Giving option 3 the stamp of approval would have resulted in a formal objection because we lacked data about a relaxed/infinite lookahead being viable or not.

An important point that keeps being overlooked is that Peter has said they'll object to the current spec (Option 3) after the lookahead research, too. The only approval they've given to the current spec is as a stepping-stone impl to infinite lookahead, but very specifically not as an alternative if infinite lookahead is unviable. There is no future in which the current spec stands and Peter doesn't object, at least given their stated opinions over the last few meetings.

LeaVerou commented 1 year ago

I'm strongly against a "mandatory &" - nothing is helped by requiring an & somewhere. (That is, div > & satisfies this but is still problematic in such a world, while > div has no problems but is mysteriously disallowed by such a restriction.) I don't understand where this suggestion is coming from or in what way it would help us.

Ok, let me explain a bit more.

Being able to skip & for selectors that don't start with an ident, is a tradeoff: we win portability (better/copy paste between nesting and @scope) and efficiency (faster to type and arguably faster to read) but "you just have to start every nested rule with a &" has far better learnability. Unlike some of the opponents of Option 3, I don't think the rule is incomprehensible to authors (heck, you may recall that Option 3 was originally called "Lea's proposal" 😁), but "every rule has to start with &" is certainly easier.

Note that div & can just be rewritten as &:is(div *), so expressive power is the same for most (all?) cases.

So I'm tending to somewhat agree with @plinss and @astearns here: if we can ship the better syntax once the unbounded lookahead investigations have finished, I'd be fine shipping a more restricted, easier to explain, form now.