-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-nesting] Require div&
, disallow &div
, for Sass compat
#8662
Comments
This would be breaking for anyone using the current specification together with something like PostCSS plugins, lightningcss, ... Given that we have been teaching users to write Having a use counter in Chrome won't say much. Edit : I think this change will shift the migration pains from users using Sass to users using PostCSS/LightningCSS/... It will also make the feature harder to teach because it again adds a weird exception. |
This is the cost of transpiling ahead of shipping implementations, yes.
Depends on how common that actually is.
What do you mean by this? This returns us to the prior rules for compound selectors, where a type selector, if present, must occur first. |
The same is true for sass. If we are arguing that the spec should be changed because sass tanspiles in a specific way we can also argue that it shouldn't be changed because PostCSS transpiles in a specific way. In principle I do agree that any polyfill that is shipped before implementations is likely to see breaking changes. But this specific change is being made to accommodate sass, not to help authors or implementations.
Maybe it is not yet too late to take this back and it won't be seen as an exception. |
Somewhat. Sass far predates CSS Nesting, and we're invading the same syntax space. This is different from projects that intentionally followed our spec, intending to match what browsers eventually ship with - there was always the chance that the spec changes before browsers ship. (It's already happened once, with the removal of The type of breakage is also significant. Any project following the current Nesting spec which allows This is distinct from the Sass problem, where (In either case, these tools all output non-nested CSS, which means their output is going to continue to be correct. The only compat problem would be if they started outputting nested CSS for newer browsers, and spat out One must also realistically consider the scale of the userbases between the projects. We're talking compat here, so actual number-of-devs-affected is more than a theoretical concern. |
PostCSS Nesting for example has ±7 million weekly installs. Whereas Sass has about ±11million. There are other projects like LightningCSS which adhere to the same principles and there are other distributions of Sass. Neither group is small enough to simply ignore :)
Correct, we have and always will follow the specification. This is the only thing that makes sense long term. |
Note that Sass's npm distribution is not the whole story—Sass is also commonly installed via Homebrew, Chocolatey, GitHub downloads, the occasional Linux distro, and so on. Sass's support for It's also worth noting that Less (~5 million weekly installs on npm) and Stylus (~3 million) both also use Sass's semantics for |
Sure, but these are still two sizable user groups. I had two concerns, one of which tabatkins addressed. 1 : That the feature would be harder to teach. But I agree with tabatkins on this. Authors who absolutely want to start every selector with 2 : That the adoption/usage of They wrote CSS that works in the current Chrome version. That they transpile their source to support other browsers and older versions of Chrome should be taken into account. Just an acknowledgment that some/any weight will given to the migration pains of these CSS authors would be sufficient.
Indeed, we will handle this similarly as we will handle the removal of
This combination is the least disruptive. |
Yes, we intentionally do not pay attention to preprocessors that attempt to lead the spec before browser support is solidified, because "ships in a major browser and sees measurable use" is the point at which we consider a feature stable. Going ahead of browsers means you're working with Explicitly Unstable And Possibly Bad Ideas. I'm being very firm here for a reason - it's incredibly hostile to all other parties to attempt to unilaterally thrust an early, unstable version of our work into "frozen in practice" stability. The browsers all have explicit steps in their launch processes for seeking and ensuring consensus and stability, and advance without those guarantees very carefully and deliberately. PostCSS and related tools do not meet that bar. It is also the case that, as a general rule, such tools do not impose nearly the "frozen in practice" weight that a browser does. They generate valid old-style code, which will continue to work as intended regardless of how we change the feature the preprocessor is implementing. The tool itself will continue to accept CSS written for it, regardless of how we change the spec, so long as authors don't update the version. The only issue arises when authors are updating their tool version but not maintaining their code; then their sites will break. But that's the case for every tool they use, for any purpose whatsoever. A syntax change is a major-version bump in semver; you must be ready to fix breakage if you accept the bump. Separate from the above, as Natalie said, if we make this change and PostCSS/etc follow, then the This is not the case for Sass/etc here - if we leave the spec as-is, then it conflicts with valid Sass/etc code that has specific, unreproducable-in-CSS behavior. And we know that it's pretty common behavior in Sass/etc. Luckily it's not the end of the world for these tools - But, since the only reason for relaxing the "type selectors must go in front" restriction was to deal with the parsing restrictions that earlier versions of Nesting imposed, and those restrictions no longer apply, and reverting to the old type-selector behavior would avoid a behavior difference with a decade-old Sass syntax that we're intentionally invading the syntax space of, it'll be nice to make the change if we can. |
I strongly agree with this and have added some guidelines to prevent this going forward. It is ok for anyone to create a tool to play around with a proposed feature before implementation, it is not ok for a tool with a large user base to act as if these are "ready for use" before they ship in actual browsers. It think it is even worse than what you are describing. By going ahead of browsers we also shape the perception of a feature and the mental model around a feature before it is ready. Every poll to gather CSS Author feedback around nesting was biased because of PostCSS Nesting and similar tools. My argument wasn't that some random PostCSS plugin should be given equal or similar weight as a browser implementation. Only that we "obfuscate" adoption of a feature in source code by transpiling it. But I agree that this is actually a good thing in this scenario. Real usage in browsers will be extremely low because anyone not writing a demo on nesting itself will use a transpiler. And these tools, as you said, have semver, ... hehe, this escalated nicely, sorry about that :) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Fun new information: it turns out that Chrome's impl never actually supported So there's zero compat issues from Chrome, at least, in returning to the previous restriction. (Thanks for tracking this info down, @andruud !) |
The CSS Working Group just discussed
The full IRC log of that discussion<fantasai> TabAtkins: In previous version of Nesting, we relaxed restriction to starting with a tag selector in order to allow & at the front<fantasai> ... which was required for previous parsing solutions <fantasai> TabAtkins: SASS uses & as a textual substitution, so if you write &div, you're asking SASS to append the letters "div", so if your parent selector was ".foo" you get ".foodiv" <fantasai> ... having this mismatch would be an annoying upgrade story for them, because this sort of concatenation is very heavily used <fantasai> ... due to object-oriented class naming patterns <fantasai> ... On the other hand, putting additional type selectors on the compound selector is exceedingly rare <fantasai> ... she's heard the request only a few times <fantasai> ... So this is very low priority for them <fantasai> ... upshot of all this, is I suggest we remove the relaxed restriction that allows type selectors to not be at the front <fantasai> ... restoring us to previous restriction, which requires the tag selector in front <fantasai> ... then you can write div& but not &div <fantasai> ... which protects that syntax space for SASS and related languages <fantasai> TabAtkins: This also helps with some degree of migration <fantasai> ... if they know it's an error, they can autocorrect to the right form <fantasai> TabAtkins: I was initially uncertain of specifying this, if there is already usage of &div in Chrome or Safari <fantasai> ... but apparently Chrome's implementation never relaxed that restriction so &div has been invalid this whole time <fantasai> TabAtkins: so at least for Chrome, this isn't an issue, so making this invalid again would be fine <fantasai> ... unclear about Safari I couldn't test <fantasai> TabAtkins: So I propose to revert the syntax restrictions <fantasai> ??: [missed] <fantasai> ??: We don't have the same behavior as Chrome, so it would be a breaking change for us <fantasai> astearns: Given that there is likely not that much content targetting Safari's current implementation, would you be ok with this change? <fantasai> ??: Pretty sure there are zero websites targetting it, so won't break the Web <oriol> q+ <fantasai> TabAtkins: Then I ask for a resolution <dbaron> s/??/matthieu/ <fantasai> s/??/mattieu/ <fantasai> s/??/mattieu/ <astearns> ack oriol <emilio> +1 to keep that restriction, fwiw on Firefox's impl I never implemented it either <oriol> Lety me reconnect <fantasai> jensimmons: Curious to know what miriam thinks about this issue <fantasai> miriam: I think this is a good idea, for the reasons Tab listed <fantasai> ... I am not on the internals of everything that Natalie is conerned about here, but was part of the conversation with Tab and agree this is the direction to go to minorly limit a problem <astearns> ack oriol <fantasai> oriol: I'm opposed to the restriction, but not clear to me how exactly it's helping. In SASS the behavior is something else, and ppl are using that behavior, if they switch to Nesting they will have to adapt somehow anyway <dbaron> s/mattieu/matthieu/ <fantasai> ... I'm not sure whether it's invalid or it means something different, if it is that relevant to people <dbaron> s/mattieu/matthieu/ <fantasai> TabAtkins: As much as possible, SASS tries not to interpret valid CSS differently as how browsers would interpret it <fantasai> ... It is helpful if we put it as invalid syntax, so it is definitely not something that would mean something in the browser <emilio> q+ <fantasai> ... It's not strictly necessary, because they'll have compat pain anyway, but a long-term goal here, is that as long as author is not using SASS-specific features, they want to emit native CSS in the future <astearns> ack emilio <fantasai> ... being certain about using CSS-compatible syntax or invalid syntax that is SASS-interpreted is a goal <fantasai> emilio: If we ever expose the final selector somehow, it would be weird if this couldn't be serialized in anyway <fantasai> ... so I support not allowing &div <fantasai> emilio: In particular, if devtools wanted to show the final selector that this element matched, you want to see something useful <fantasai> ... if you write &div, you can't just expand it <fantasai> emilio: so I would prefer to avoid this special case <fantasai> astearns: Other comments or conerns? <fantasai> s/conerns/concerns/ <fantasai> TabAtkins: Proposed to remove relaxation of type selector rules, keep current rule that type selector must be first in a compound selector <fantasai> astearns: objections? <fantasai> RESOLVED: type selector remains required first; &div is invalid |
All right, spec should be updated to this condition now. We'll need to update the tests (and probably add some additional ones). |
… so &div is invalid and div& is valid. w3c/csswg-drafts#8662
Given the very heartening news that infinite-lookahead is viable in Chrome, I'd like to try and revisit one of our syntax changes caused by Nesting.
In the original version of the spec, you had to start a selector with
&
, so to handle the case where you want to add a type selector, we relaxed the restriction that a type selector had to be the first thing in a compound selector. This allowed&div
to work, thodiv&
was theoretically okay (in cases like@nest div&
).In the current version of the spec, you still can't start a selector with an ident, so
&div
is still the right way to spell things most of the time (but again, still okay in theory to do the other way, like.foo div&
).Neither of these restrictions will apply anymore if #7961 goes thru. Which is good, because
&div
is terrible for Sass.Sass essentially uses text concatenation for its nesting feature. If you write
.foo { &div {...}}
in Sass, it generates a.foodiv {...}
rule - a single larger class selector. In CSS Nesting, this is instead equivalent todiv.foo {...}
- a type selector plus a class selector.This mismatch in syntax was always going to be an enormous pain for Sass to migrate to CSS Nesting (possibly a straight-up blocker, requiring Sass users to explicitly opt into CSS Nesting instead), but when other factors made
&div
the preferred form, I accepted that it was just one of those painful situations that'll be worth it in the long term.But given #7961, there's no longer any reason to prefer
&div
overdiv&
. So we can simultaneously (a) remove a syntax change, preserving the original syntax of Selectors that has been stable for a long time, and (b) make Sass's task of migrating to CSS Nesting natively massively easier (along with any other preprocessor that has a similar feature, but I'm familiar with Sass's syntax here).I've talked with @andruud about this and he's dropping a Use Counter into Chrome preemptively, to make sure we'll actually be able to make this change. (Since we're shipping the current Nesting spec in Chrome 112 which is just now releasing to Stable.)
/cc @nex3
The text was updated successfully, but these errors were encountered: