Re: [csswg-drafts] [css-cascade-5] Allow authors to explicitly place unlayered styles in the cascade layer order (#6323)

All these approaches get a bit messy when we put them into a nested context — which [@alohci pointed out](https://github.com/w3c/csswg-drafts/issues/6323#issuecomment-874354775) is un-avoidable. The keyword option only works if we nest entire blocks, but becomes semantically unclear when using the nested name syntax:

```css
@layer up framework {

    @layer down defaults { … }

    @layer up components { … }

}

/* how does this utilities layer relate to framework.<unlayered>? */
@layer up framework.utilities;    
````

The implicitly named override layer (e.g. `!important`) can be repeated at each level, but the result is verbose:

```css
@layer !important.framework.!important.utilities;
```

-------

After a conversation with @fantasai, we're proposing a variation on the original proposal, using the `initial` keyword in layer list declarations. But rather than placing it once, like other layer names, we would treat it as a relational anchor for the other layers in the list. The following declarations can be folded together:
    
```css
/* each use of initial is scoped to that layer rule */
@layer reset, initial, utilities;
@layer defaults, initial, overrides;

/* the result maintains relations to initial */
@layer reset, defaults, initial, utilities, overrides;
```

There is still a single layer stack (and shared namespace) for layer names at any level, and layers still default to placement before/under the `initial` layer, unless placed after `initial` in a list. Authors could also use a convention to achieve more explicit under/over layer names, if desired:

```css
/* can be defined at any level of nesting */
@layer down, initial, up;

/* or even described in the nested syntax */
@layer up.framework.initial, up.framework.up.utilities;
```

There is still potential for name collisions that change the intended layer order, but those collisions are limited to author-defined layer names (which can already collide). In this case we would want to follow established conventions for name collision — such that the first mention takes precedence. For example:

```css
@layer initial, framework;
@layer framework, initial;
```

Results in a single `framework` layer above the `initial` unlayered styles. The inverse can also be resolved using our existing rules. Any of these options result in `framework` being placed below `initial`, since the first mention of `framework` has it placed either explicitly or implicitly below:

```css
/* single list */
@layer framework, initial, framework;

/* split v1 */
@layer framework;
@layer initial, framework;

/* split v2 */
@layer framework;
@layer initial, framework;
```

Note: Given that approach, the following are meaningless, and should be treated as invalid:

```css
/* nothing is being anchored */
@layer initial;

/* can't have two anchors in one statement */
@layer initial, framework, initial;

/* initial is not a layer that accepts sub-layers */
@layer initial.resets;
```

We think the combination of a list-anchoring syntax, combined with the option to create more explicit conventions, should cover the majority of use-cases — but we'd love to get more feedback here. Especially from authors.

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


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

Received on Friday, 15 October 2021 22:59:56 UTC