- From: Ibby Wedin via GitHub <sysbot+gh@w3.org>
- Date: Tue, 13 Sep 2022 05:10:50 +0000
- To: public-css-archive@w3.org
By my reading of the spec, this construction already has an unambiguous meaning.
```
.a {
& .b {
@nest :not(.c)& {
color: red;
}
}
}
/* With explicit `:is` expansion,
the innermost selector would be: */
:not(.c):is(:is(.a) .b) {}
/* reordering pseudo-classes */
:is(:is(.a) .b):not(.c) {}
/* removing redundant inner :is */
:is(.a .b):not(.c) {}
/* I'm pretty sure the remaining :is
is also always redundant. */
.a .b:not(.c) {}
```
I _think_ I got all that right, anyway.
The other case bottoms out, by my understanding, into something vaguely close to the desired output, but much more permissive by matching `:not(.c)` in _any_ ancestor position.
```
.a {
& .b {
@nest :not(.c) & {
color: red;
}
}
}
/* expansion of innermost selector */
:not(.c) :is(:is(.a) .b) {}
/* removing inner :is */
:not(.c) :is(.a .b) {}
/* This transformation is probably less
tractable generally, but
distributing
:not(.c) is valid in this case, I think. */
:is(
:not(.c) .a .b,
.a:not(.c) .b,
.a :not(.c) .b
) {}
```
Here is something that simplifies in the desired way, but requires the repeating of the `.a` in the innermost selector.
```
.a {
& .b {
@nest .a:not(.c) &
}
}
/* expansion of innermost selector */
.a:not(.c) :is(:is(.a) .b) {}
/* removing inner :is */
.a:not(.c) :is(.a .b) {}
/* because .a:not(.c) is more selective than .a */
.a:not(.c) .b {}
```
In this case, `.a` could instead be any single selector, but repeating a gnarly outer selector deeper down is obviously not that good.
This is where I see the semantic and syntactic holes lining up. Since the syntax that motivated this request already has a simple, consistent meaning, we would need new syntax to ease the repetition burden.
I think the direct solution would be a way to refer to outer selectors, for instance allowing `&2`, `&3`, etc to appear in any selector that also includes either a bare `&` or the equivalent `&1`.
Another possibility: Custom selectors would solve the repetition problem generally, at the cost of a little cruft to define the selector name. Being able to place a hypothetical `@custom-selector` inside a declaration block to give a scoped name to `&` would be a delightful trick.
```
.a {
@custom-selector :--granny &
& .b {
@nest --granny:not(.c) &
}
}
```
This way, there would be no truly new syntax (just a novel combination of two proposed standards). Parsing custom selectors, I think, doesn't require much more than expanding the syntactic sugar, but there could also be some dark corners there.
At any rate, it's something a preprocessor could support as long as it properly wraps the referent of `&` in `:is` during expansion. It's probably worth seeing if any preprocessors can be configured to perform the necessary transformations correctly; if they follow the spec as it stands, I don't _think_ things would get out of hand.
--
GitHub Notification of comment by WCWedin
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/6977#issuecomment-1244905968 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Tuesday, 13 September 2022 05:10:54 UTC