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

I think the goal of the proposed change is to have syntax closer to SCSS and to have hopefully better developer ergonomics to avoid common programming errors. This would be via the "parser switch" model vs an `&` before each rule. Let me know if I missed any other goal. :)

**Pros**
- Folks who aren’t thrilled to add an `&` before their nested selectors will appreciate the familiarity and convenience of the new proposal. They’d also appreciate the flexibility to use more than one way of expressing the syntax.

**Cons**
- The learning curve increases for anyone not coming from SCSS, because the previous syntax's simplicity and rigidity was a feature. Folks who do know SCSS still have things to learn, it's not a free switch. For example, BEM style nesting won't port over and most copy/paste scenarios will require throwing the `@nest;` switch in "just in case" or an "I don’t know why, I just always put it there". 
- The original feedback to the nesting spec was that there were too many options. Hence the "always @nest" survey option in the [nesting syntax survey](https://developer.chrome.com/blog/help-css-nesting/) (results [post found here](https://developer.chrome.com/blog/help-css-nesting-results/)), which tried to gather data about this point. This proposal both increases the options and is more to learn / be aware of, going counter to earlier spec feedback and concerns.
- Increasing the flexibility also increases the potential for accidental programming errors. More options also means more cases to be aware of, or the style sheet ends up with errors. It gives some but takes some. Increased flexibility also means ramping up to more nesting styles when reading other authors’ nested styles, and increases friction to understanding style sheets between teams (or even within the same team between selectors that do or don’t have `@nest;` or when importing third-party sheets.
- Seeing `@nest` somewhere was a strong signal of a complex nesting scenario, which felt appropriate when reading code. Using `@nest` is also pretty rare, so it really meant something when you saw it (unless a team chooses to `@nest` everywhere, then it loses this specialty signal). 
- The proposed changes don't make SCSS directly copy/pastable as it sought to, which means we can't promise "just paste" SCSS and go. SCSS still holds super powers not present in this proposed addition to nesting, potentially putting this spec into an uncanny SCSS style instead of a CSS way. 
- It was also simple to teach before as it had few rules to be mindful of. I love CSS flexibility, but the basic rules of the current spec still have enough difficult cases that we may not want to add flexibility so that understanding of intent is clear for both people and parsers.
- Lastly, while this proposed change is very considerate to SCSS users, it's not considering [LightningCSS](https://lightningcss.dev/), [postcss-preset-env](https://github.com/csstools/postcss-preset-env) (which [Vite](https://vitejs.dev/) uses by default) or [esbuild](https://esbuild.github.io/), all of which parse and compile the draft spec. While SCSS users are seeking familiarity, these folks are more than content with nesting as is. They've been battle testing it for over a year without requests to remove `&`.
- Because of all of these cons, I feel that we should at least not jump to changing the spec right now, and perhaps consider these changes for a level 2 spec, since the proposed changes are more-or-less backwards compatible.
- Below is an enumeration of the possible ways to nest. The current spec has two ways (start with `&` or start with `@nest`), and the proposed changes make it 4 (the two original styles,  `@nest; …` and first-selector-starts-with-`&`). I thought it would be useful to write them out so that everyone can see the actual syntax options in practice.
Current spec options for nesting

```css
.foo {
  & .bar {}
  &.bar {}
  & > .bar {}
  &:hover {}

  @nest .qux & {}
  @nest .qux& {}
  @nest .qux > & {}
  @nest .qux &:hover {}
}

.foo {
  @nest & .bar {}
  @nest &.bar {}
  @nest & > .bar {}
  @nest &:hover {}

  @nest .qux & {}
  @nest .qux& {}
  @nest .qux > & {}
  @nest .qux &:hover {}
}

/* specialty case, nesting @media, no `&` required unless creating new nested selectors */
.foo {
  --brand: hotpink;

  @media (prefers-color-scheme: light) {
    --brand: rebeccapurple;
  }
}
```

Proposed options for nesting

```css
.foo {
  @nest;

  .bar {}
  &.bar {}
  > .bar {}
  &:hover {}

  .qux & {}
  .qux& {}
  .qux > & {}
  .qux &:hover {}
}

.foo {
  /* moved &.bar to first selector to trigger parser switch, if it's removed the rest break..? */
  &.bar {}
  .bar {}
  > .bar {}
  &:hover {}

  .qux & {}
  .qux& {}
  .qux > & {}
  .qux &:hover {}
}

/* previous syntax options still work */
.foo {
  & .bar {}
  &.bar {}
  & > .bar {}
  &:hover {}

  @nest .qux & {}
  @nest .qux& {}
  @nest .qux > & {}
  @nest .qux &:hover {}
}

.foo {
  @nest & .bar {}
  @nest &.bar {}
  @nest & > .bar {}
  @nest &:hover {}

  @nest .qux & {}
  @nest .qux& {}
  @nest .qux > & {}
  @nest .qux &:hover {}
}

/* unchanged */
.foo {
  --brand: hotpink;

  @media (prefers-color-scheme: light) {
    --brand: rebeccapurple;
  }
}
```

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


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

Received on Friday, 7 October 2022 23:22:31 UTC