CSS nesting specification


#21

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.


#22

@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.


#23

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.


#24

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.


#25

From what I am reading @tabatkins my example above is matching your thinking.

So:

  • .thing { @nest { .thing {
    • is .thing .thing {
  • .thing { @nest { &.thing {
    • is .thing.thing {
  • .thing { @nest { &:hover {
    • is .thing:hover {
  • .thing { &:hover {
    • is .thing:hover {

If that is the case, I’m very very happy.


#26

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.


#27

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


#28

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.


#29

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.


#30
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 {
    ...
  }
}

#31

Yes, once you can nest MQs into style rules, those two pieces of code are indeed equivalent.


#32

Shouldn’t the media query be inside the nest?

.selector {
  @nest {
    @media screen {
      …
    }
  }
}

#33

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 {
      ...
    }
  }
}

#34

That’s a rather beautiful solution; nice work!


#35

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.


#36

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.