[csswg-drafts] [css-nesting-1] Should code portability trump coding habits wrt nesting syntax? (#8029)

FremyCompany has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-nesting-1] Should code portability trump coding habits wrt nesting syntax? ==
As a follow-up from #7834, the question of the "same-brace-but-inconsitent-prefixing" (Proposal 3) vs "other-brace-but-consistent-prefixing" (Proposal 4) was left open. Proposal 3 is described in the [current editor draft](https://drafts.csswg.org/css-nesting/). The presentation of Proposal 4 and the related discussion can be found here: https://github.com/w3c/csswg-drafts/issues/7834#issuecomment-1292144760

**The main advantage of Proposal 3**... 
> is that this should be very familiar to anyone who might have used nesting through CSS preprocessors, although the requirement to use `&` or `:is()` in some cases is new as preprocessors don't limit themselves to the more efficient types of parsing which browsers rely on for performance reasons.

**The main advantage of Proposal 4...** 
> is that it provides full interoperability between contexts: you can take any CSS code you have today, wrap it in a block, add a selector prefix, and now you have "nested" the existing code without having to make any change. Similarly, moving from and to CSS Scoping blocks does not require any change at all. Finally, if some code needs to be un-nested (because it is moved to a Web Components CSS file and no longer requires a prefix), this can be done without any change to the CSS.

Apart from the requirement to put the rules in another brace, the syntax between the two proposals looks remakably simliar, as can be seen in the following examples:

<table>
<thead><tr><th>Proposal 3</th><th>Proposal 4</th></tr></thead>

<tr><td>

- Is familiar to users of CSS preprocessors.
- Every CSSStyleDeclaration block can now support nested rules

</td><td>

- Code portability between regular stylesheets rules, nested rules, scoped rules, and web component rules.
- Does not put major syntax restrictions on the declaration block.

</td></tr>

<tr><td>

- Rules are invalid if they start with a type selector, requiring them to be rephrased somehow. (Using :is(div), starting with &, etc.)
- This prevents us from changing property syntax to start with an ascii glyph in the future.

</td><td>

- Requires another pair of brackets
- If you are only nesting rules, you still need an empty declaration block ({}), which looks awkward
- Nesting is not secured by default for the others CSSStyleDeclaration context (e.g. inline styles)

</td></tr>

<tr><th>Spec example 1</th><th>...</th></tr>

<tr><td>

```css
table.colortable {
  & td {
    text-align:center;
    &.c { text-transform:uppercase }
    &:first-child, &:first-child + td { ... }
  }
  & th {
    text-align:center;
    background:black;
    color:white;
  }
}
```

</td><td>

```css
table.colortable {} {
  td { text-align:center; } {
    &.c { text-transform:uppercase }
    &:first-child, &:first-child + td { ... }
  }
  th {
    text-align:center;
    background:black;
    color:white;
  }
}
```

</td></tr>

<tr><th>Spec example 2</th><th>...</th></tr>

<tr><td>

```css
.foo {
  color: red;

  .bar {
    color: blue;
  }
}
```

</td><td>

```css
.foo { color: red; } {
  .bar {
    color: blue;
  }
}
```

</td></tr>

<tr><th>Spec example 3</th><th>...</th></tr>

<tr><td>

```css
div {
  color: red;

  & input { margin: 1em; }
}
```

</td><td>

```css
div {
  color: red; } {

  input { margin: 1em; }
}
```

</td></tr>

<tr><th>Integration with layers</th><th>...</th></tr>

<tr><td>

```css
@layer base {
  html {
    block-size: 100%;

    @layer base.support {
      & body {
        min-block-size: 100%;
      }
    }
  }
}
```

</td><td>

```css
@layer base {
  html {
    block-size: 100%; } {
    
    @layer base.support {
      body {
        min-block-size: 100%;
      }
    }
  }
}
```

</td></tr>

<tr><th>Integration with scope</th><th>...</th></tr>

<tr><td>

```css
.card {
  inline-size: 40ch;
  aspect-ratio: 3/4;

  @scope (&) to (> header > *) {
    :scope > header {
      border-block-end: 1px solid white;
    }
  }
}
```

</td><td>

```css
.card {
  inline-size: 40ch;
  aspect-ratio: 3/4; } {

  @scope (&) to (> header > *) {
    :scope > header {
      border-block-end: 1px solid white;
    }
  }
}
```

</td></tr>

</table>

Regarding the question of nested rules in the style attribute, I would rather have rules contained in a `<style>` element where they can receive the space needed. There is a proposal for this already, for instance:

```html
<article>
    <style>
        :style-root { } {
            h1 { color: purple; }
        }
    </style>
    <h1>Title</h1>
    ....
</article>
```

Otherwise, we can also put them in another attribute named cssRules="..." which contains the content of the second (rule) block.

Anything I missed in the discussion?

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/8029 using your GitHub account


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

Received on Sunday, 6 November 2022 17:38:45 UTC