[csswg-drafts] [css-cascade] Proposal: `@layer initial` always being the first layer (#10094)

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

== [css-cascade] Proposal: `@layer initial` always being the first layer ==
## Problem

Currently, layers all need to be explicitly defined. This means the page author needs to be very disciplined in setting their layer order upfront, before adding any “real” styles.

This almost always involves creating a layer named something like “defaults” early on.

```html
<head>
  <style>
    @layer defaults, components, utilities;
  </style>
  <link rel=“stylesheet” href=“styles.css” />
</head>
```

This works, but is problematic for a few reasons:
- If this layer order is not set upfront, then any styles that come before `@layer defaults` can potentially declare layers that come first.
- It requires everyone to be aware of the name `defaults` if they want to declare low-priority styles later.
- It hinders the adoption of libraries that want to use cascade layers, because they need to instruct page authors to set up layer order correctly.
- Every shadow-root needs to come up with its own `defaults` layer.
  - See [default stylesheets proposal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Default-Stylesheets-Concept-and-Proposal.md) from almost a decade ago.

## Proposal

Allow authors to declare all low-priority styles in a layer named `initial`.

```css
@layer initial {
  *, ::before, ::after {
    box-sizing: border-box;
    margin: 0;
  }
} 
```

`initial` is one of the layer names that are ["reserved for future use"](https://www.w3.org/TR/css-cascade-5/#layer-names), so this layer can be automatically set up by the browser, such that:
1. It is *always* the first layer that comes before all other .
   - It is always the first within a context (e.g. shadow context vs host context vs document context).
2. It always exists automatically, i.e. it doesn’t need to be explicitly created.
   - This means `@layer initial` exists implicitly, regardless of the page’s layer order, similar to the implicit “outer” (unlayered) layer.

```css
@layer A, B;

@layer initial {
  /* this will cascade before A and B */
}
```

### Polyfill

In my testing, I found that the three major browsers do not do anything special to the “reserved” layer names, even though the spec says these must be invalid at parse time. I initially thought this was a bug and/or maybe the spec should be changed (see #10067), but then I realized that the current browser behavior makes this feature somewhat easy to polyfill, by setting `@layer initial;` as the very first style. This could even be done automatically by frameworks.

```html
<head>
  <style>@layer initial;</style>
  …
</head>
```

## Use cases

This solves all of the problems described above, and makes cascade layers easier to incorporate into existing workflows.

- Page authors and component authors alike can easily add styles to the initial layer, without having to come up with a carefully-coordinated layer setup.
- CSS “resets” (such as [“CSS remedy”](https://github.com/jensimmons/cssremedy)) can be distributed with all styles pre-wrapped in `@layer initial`, with a guarantee that they will come first.
- Component library authors can use CSS layers more liberally, without having to worry about third-party resets potentially being in higher-priority layer.
  - Page authors may not even need to care about a component library’s CSS internally using cascade layers.
- Outer context styles that are [adopted](https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptedStyleSheets) into an inner context can use `@layer initial` for their default styles, even though `.adoptedStyleSheets` is ordered after the inner context’s own `.styleSheets`.
  - This is particularly important for [open-styleable shadow roots](https://redirect.github.com/WICG/webcomponents/issues/909), where document stylesheets *may* be ordered after shadow-root’s styles. `@layer initial` will provide a canonical way to deprioritize certain styles without being impacted by order of appearance or existing layer order.

## Open questions

Should `initial` also be implicitly set up for nested sub-layers?

```css
@layer foo {
  @layer A, B;

  @layer initial {
    /* comes before foo.A and foo.B */
  }
}
```

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


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

Received on Saturday, 16 March 2024 22:36:17 UTC