Re: [csswg-drafts] [css-nesting-1] Clarify when nested rules are equivalents to `:is()` (#10523)

> I want to make sure that I understand this behavior properly:

No problem, glad that helped. In the meantime, I'm going to close this as 'question answered' if you don't mind.

> 1. In all cases of nested selectors, the nearest "true equivalent" will be a selector that uses the `:is()` pseudo-selector

right

> 2. Both the parent _and_ the nested selector(s) would be considered to be wrapped in an`:is()`  (e.g. `article { h1 {display: block}}` => `:is(article) :is(h1)`

no, only the `&` should be thought of as similar to `:is(<parent>)`

> 3. the _unnested_ `&` ends up representing `*` (e.g. `& {display: block;}` => `:is(*) {display: block}`)

No, see the [Editor's Draft](https://drafts.csswg.org/css-nesting/#nest-selector) (emphasis added): 

> When used in the selector of a nested style rule, the nesting selector represents the elements matched by the parent rule. _When used in any other context, it represents the same elements as `:scope` in that context (unless otherwise defined)._

This is also often equivalent to `:root`, when not in scoped situations. According to [this previous resolution](https://github.com/w3c/csswg-drafts/issues/8088#issuecomment-1371590352) it has a specificity of `0` in those situations.

> 4. The nested `&` that doesn't have any inline selectors is a _single_ application of `:is()` where it's the _parent_ that's wrapped in an `:is()`. e.g. ( `section > article { & {display: block}}` => `:is(section > article)`
> 5. The nested `&` that _does have inline selectors_ is a multi-application of `:is()` because it comes from both parent and nested child. e.g. `section > article {main & {display: block}}` => `:is(main) :is(section > article) {display: block}`

As far as I can tell, only the `&` should ever be treated 'like' `:is(<parent-selector>)`. There is never any need to think of the nested selector as though it is wrapped. I've confirmed that with a [quick test of the resulting specificity](https://codepen.io/miriamsuzanne/pen/abgbRoa) on codepen.

> 6. double-& is a double-chained `:is()`, but the reality is that it has nothing to do with what's nested. It's because nesting triggers children and parents to be wrapped in `:is()`, and in this case we've just chained our parent `:is()` together.
>
> ```
> article { /*:is(article):is(article) */
>  && {
>   display: block;
>  }
> }
> 
> .article {
>  && { /* :is(.article):is(.article) */
>    display: block;
>  }
> }
> ```
> 
The replacement is a metaphor, but a fairly reliable one. The `&` is a selector that matches the same elements as the parent selector, with `:is()`-like implications. And it can be chained as desired. 

The big difference here is that Sass does literal string replacement, which can change the selector meaning based on context – `.foo { &bar {}}` becomes `.foobar`. But CSS does not do any replacement, so the `&` selector has the same meaning no matter how you combine it with other things. It means: _the same elements as above_. In that case the direct `:is()` replacement doesn't work (`:is(.foo)bar`) – but the same meaning still holds. We just have to turn it around to get the equivalent `bar:is(.foo)`.

But yes, in your case, the chained-`is()` metaphor continues to be reliable.

> I know that the nesting behavior _superficially_ looks / acts like Sass. But what I'm really trying to understand is all the ways it _isn't like Sass_.
> 
> Sass of course errors on a single nested `&`. It also wouldn't allow an unnested `&`, nor would it allow `&&`, all of which aren't problematic in CSS.

Besides the impact on specificity, and the inability to do string-concatenation, [this thread](https://github.com/w3c/csswg-drafts/issues/8310) covers the biggest difference that I would note. Here's [a codepen demo of the difference](https://codepen.io/pen?editors=1100).

> Do you think it might be beneficial to explain explicitly in the documentation how nesting invokes `:is()` on both parent _and_ child and to possibly even give an example of the unnested `&` so as to illustrate how it _also_ uses `:is()` ?

I don't believe those assertions are correct. :) 

But it's possible @tabatkins will want to clarify some of the examples based on this conversation, I'm not sure. 

-- 
GitHub Notification of comment by mirisuzanne
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10523#issuecomment-2215656827 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 9 July 2024 00:12:47 UTC