Re: [csswg-drafts] [css-nesting] Problems with indiscriminately wrapping all parent selectors with `:is()` (#9492)

> It may help to explain your reasoning rather than just vetoing things.

Yes, I did explain my reasoning, in an immediately preceding comment, and this topic was discussed in older Nesting discussions already so I wasn't sure of how much I should repeat. I posted my veto as a separate comment, rather than just editting my previous ones, to make sure it was expressed in the email record as well.  Let me be more explicit, tho.

As expressed in the call again, by me and Oriol, we *cannot* solve the general case of making specificity match that of fully-unnested rules, because that entails an exponential explosion of possible specificities.

For example, given:

```css
div, .div, #div {
 div, .div, #div {
  div, .div, #div {
   div, .div, #div { ... }
  }
 }
}
```

There are already 3^4 = 81 unique specificities that the innermost properties could potentially have, depending on what precisely they matched. Adding another level would triple it again, to 243; adding a fourth selector to each level would similarly roughly triple it to 4^4 = 256.

There's no workaround here. An author writing out a selector list with 256 options can easily see there might be a performance issue with that. An author writing four nested rules, each relatively short, might not be aware of that at all. And it's only a short step away from *millions* or paths, or more.

In the call, you suggested we could do some intelligent coalescing of specificities at each level; if the author writes `.foo, .bar, .baz, ...` it doesn't matter how long the list is, every option's specificity is `[0, 1, 0]`. (@FremyCompany also just suggested this, above.) This doesn't solve the general case, however; at best it can slow down the exponential growth, but not prevent it, and the example I wrote above wouldn't be helped by it at all, since every option has a different specificity anyway. So this is similarly unworkable; it's still easy for authors to exceed the compute budget, accidentally or intentionally.

-----------

However, while the *general* case is unsolveable, the *specific* case of `.foo, #bar { @media (...) { color: red; } }` wanting to have the same specificity as if it were nested the other way around *is* solveable.

As I said, I'd object to treating a rule with a lone `&` differently; this sort of context-sensitivity is confusing for authors and means that seemingly-innocent changes like adding an additional selector to a list can change the meaning of *other* selectors they didn't touch.

But adding a *new* construct that explicitly handles this case is fine. I alluded to this above, so let me give the proposal more explicitly:

Add a new `@nest` rule. It has no prelude, and allows nested properties inside of it. It matches exactly the same elements and/or pseudo-elements as the parent rule, and applies its nested properties to those elements with the same specificity as the parent rule. Use `@nest` as the wrapping rule for properties after at-rules, or for naked properties in conditional rules (rather than an `& {...}` rule, as currently specified).

Examples:

```css
div, .foo, #bar::before {
 color: blue;
 @media (...) { color: red; }
 color: green;
}

/* Today, desugars to: */

div, .foo, #bar::before {
 color: blue;
 color: green;
}
@media (...) {
 :is(div, .foo) { color: red; } 
 /* different specificity, and loses the `::before` selector :( */
}

/* With @nest, it'll be treated as (and reflected in the OM as): */

div, .foo, #bar::before {
 color: blue;
 @media (...) { 
  @nest { color: red; } 
 }
 @nest {
  color: green;
 }
}

/* Which desugars to: */
div, .foo, #bar::before {
 color: blue;
}
@media (...) {
 div, .foo, #bar::before { color: red; }
}
div, .foo, #bar::before {
 color: green;
}
```

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


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

Received on Wednesday, 25 October 2023 17:29:19 UTC