Re: [csswg-drafts] [css-nesting-1] Syntax Invites Errors (#7834)

Having spend more time thinking about it I keep coming back to `@nest` blocks.

I like that proposal 3 introduces rules that make it possible to have relative selectors.
I also like that those same rules make `@nest` unneeded in all but one case, nested selector starts with a tag selector (or an ident token).

But in a way `@nest` is similar to parentheses in `calc()`.
It helps authors express what they mean without side effects and without requiring extra and very specific knowledge.

`calc(10 + 3 * 5)` is not ambiguous in any programming language because operator precedence is well defined. But not all authors find it easy to switch to this math context. It is ambiguous because we known about operator precedence and that left to right doesn't apply here, but we might not exactly remember how it all fit together.

Adding parentheses `calc(10 + (3 * 5))` is more verbose, totally unneeded but it still helps a lot of authors to write and read this bit of code.

What I don't like about proposal 3 is that it forces authors to find their own way to write unambiguous selectors. There is no syntax provided by the language that is side-effect free.

It would be like having to write `calc(10 + max(3 * 5))`. You have to know that `max()` is fine with just one argument and that it doesn't have any other effects, but it is a very poor expression of wanting to disambiguate the calc expression. A future reader might attribute special significance to `max` which just doesn't exist in this context.

------------------

Invalid :

```css
.some {
  /* any styles */

  dialog {
    color: purple;
  }
}
```

Valid :

In these examples `:modal` is picked because it is a relatively new pseudo selector that is still invalid in a large portion of browser versions in use.

```css
.some {
  /* any styles */

  :is(dialog) {
    color: purple;
  }

  :is(dialog):modal {
    color: purple;
  }

  /* this has a side-effect in theory, making copy-paste harder */
  :is(dialog:modal) {
    color: purple;
  }

  :is(dialog):modal, other {
    color: purple;
  }

  /* this has an actual side-effect */
  :is(dialog:modal), other {
    color: purple;
  }
}
```

Authors have to consider all the effects of `:is()` and all the effects of bits of their selector and exactly wrap the right part. But this information is then ambiguous to their future self and other authors. Did they intend exactly `:is(dialog:modal), other` or did they just wrap the first compound selector because it looks logical.

I don't think `:is()` is suited for this purpose because it isn't side-effect free and it doesn't match what the author is trying to do (write a nested selector).

`:where` and `:not` is worse.

`@nest` blocks solved this elegantly. It provided a syntax for authors to express exactly what they intended without any side-effects.

Not saying that `@nest` has to be `@nest` exactly, but I think the problems it solved remain in part with proposal 3.

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


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

Received on Wednesday, 19 October 2022 06:20:32 UTC