You’d still be required to use the nesting selector inside of @nest, for precisely the lack-of-clarity issues you raise. Your example would thus be invalid. You’d have to write either & .bar
or &.bar
.
@Edwin_Reynoso unless the & .thing
case @tabatkins just mentioned could be removed then I don’t see it as possible.
.thing {
@nest {
.thing {...}
}
}
Could mean:
.thing .thing {...}
And:
.thing {
@nest {
&.thing {...}
}
}
Could mean:
.thing.thing {...}
Which if possible I would probably prefer @nest
for multiple selectors, if not then the use-case is pretty slim in my opinion.
Ampersand syntax looks nice, but how will it handle nested @rules? Or are nested @rules—like @media—not supported?
I do however feel that the ampersand syntax creates inconsistencies. Depending on whether you want to pre- or suffix your selector, you’ll have to use the @nest rule. A nesting block prevents this, be it curlies or another character.
Ampersand syntax looks nice, but how will it handle nested @rules? Or are nested @rules—like @media—not supported?
Nothing special needs to be done for nested at-rules. As I said before, the sole grammatical ambiguity is that a selector starting with a tagname followed by a pseudo-class looks like a declaration. Anything else is fine, including at-rules, which start with an at-keyword token. (To handle nested at-rules just needs some additions to the CSSOM, to add a .childRules
property to the CSSStyleRule interface.)
I do however feel that the ampersand syntax creates inconsistencies. Depending on whether you want to pre- or suffix your selector, you’ll have to use the @nest rule. A nesting block prevents this, be it curlies or another character.
The @nest
rule will allow you to use any nested rule, whether the &
appears at the start or elsewhere, so if you want a simpler model, feel free to use it all the time. (It’s identical to the Nesting Block, after all, just with the five extra characters of “@nest”.) The idea is just that, in the common case where you start with &
, you don’t need to pay the extra cost of the wrapping block.
From what I am reading @tabatkins my example above is matching your thinking.
So:
-
.thing { @nest { .thing {
- is
.thing .thing {
- is
-
.thing { @nest { &.thing {
- is
.thing.thing {
- is
-
.thing { @nest { &:hover {
- is
.thing:hover {
- is
-
.thing { &:hover {
- is
.thing:hover {
- is
If that is the case, I’m very very happy.
No, I’ve explicitly contradicted that:
You’d still be required to use the nesting selector inside of @nest, for precisely the lack-of-clarity issues you raise. Your example would thus be invalid. You’d have to write either & .bar or &.bar.
So your first example is invalid, and needs to be written .thing { @nest { & .thing {
. But the rest are valid and correct per my intentions, yes.
I thought you had just wanted to confirm as I thought you were saying the opposite with your last comment.
The &space
could be implied when in @nest
, this is how LESS works which seems fairly intuitive and only really required for pseudo and more specificity.
Thanks
You argued in http://discourse.wicg.io/t/css-nesting-specification/839/22 that that very syntax was confusing, because it wasn’t clear which the author meant. I agree with you; I’m unsure why you’ve reversed your position or what your new reasoning for it is.
Nesting without an & is confusing, because it’s not immediately clear whether you mean to extend the last compound selector or start a new one. It’s also bad because it defaults to the descendant selector, which is relatively slow; we shouldn’t be making that the easiest case.
Yeah perhaps I didn’t really make my point clear at all, I was stating the decisions needed with the syntax rather than it was actually a show stopper.
If it was defined in the spec as it soon wouldn’t become confusing I feel.
I’m happy for either case to be a default, it seems that a descendent selector would be more common however I get the hesitation to do neither also.
It seems that besides when nesting a selector within a new parent selector @nest
has limited use otherwise.
My use case personally is for defining custom elements and all the behaviour and elements within them. So the @nest
with descendant selectors seems a very common case in the files to me.
thing { &:hover {
// equal
.thing:hover {
it seems weird to accept that and reject
thing { .parent:hover & {
// equal
.parent:hover & .thing{
@tabatkins I get your argument about syntax issues, so I would go for only supporting @nest + mandatory &. KISS.
For media queries can you confirm my expectations:
.selector {
@media whatever {
@nest {
&:hover {
...
}
}
}
}
// equal
@media whatever {
.selector:hover {
...
}
}
Yes, once you can nest MQs into style rules, those two pieces of code are indeed equivalent.
Shouldn’t the media query be inside the nest?
.selector {
@nest {
@media screen {
…
}
}
}
No particular need to. Once given the ability to nest MQs, they can just be put directly in.
Note that @nest is slightly refined; it’s effectively just a style rule, and takes a selector between the @nest
and the {
. So the first example in @MoOx’s last post would be:
.selector {
@media whatever {
@nest &:hover {
...
}
}
}
or, since you can omit @nest
when the selector starts with &
, just:
.selector {
@media whatever {
&:hover {
...
}
}
}
That’s a rather beautiful solution; nice work!
Could somebody give a code example explaining the need for @nest
? It seems like it’s just a concession to ease of LR tokenization at the expense of ease of human authorship. As @MoOx points out, it’s a really arbitrary distinction for authors, one that seems just as prone to the kind of re-factorization nightmares as @tabatkins mentioned for comma-separated lists.
Yes, it’s exactly a concession to ease of parsing. CSS currently never requires more than one token of lookahead; naive Nesting requires arbitrary amounts of lookahead, which isn’t acceptable to browsers.
So, the Nesting spec allows direct nesting where it can be immediately disambiguated (when it starts with &
), and requires @nest
otherwise.