Skip to content

Commit

Permalink
Pull childless @layer rules to the top of the output stylesheet
Browse files Browse the repository at this point in the history
These rules are only allowed at the beginning of stylesheets. Allowing
them anywhere in Sass and moving them to the top of the output matches
the behavior of plain-CSS `@import` rules.

Closes #3842
  • Loading branch information
nex3 committed Apr 19, 2024
1 parent 92c48d2 commit 656c035
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions spec/at-rules/extend.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ shorthands:
* `extend(extendee, extensions)` for iteratively running `extendee =
extend(extendee, extension)` for each `extension` in `extensions`.

### Initial Rule

An "initial rule" is a CSS at-rule that is either an `@import` or a `@layer`
rule with no children.

## Semantics

The `@extend` rule means that all elements matching the [extender](#extender)
Expand Down Expand Up @@ -208,26 +213,44 @@ that includes CSS for *all* modules transitively used or forwarded by
> Because this traverses modules depth-first, it emits CSS in reverse
> topological order.
* Let `initial-imports` be the longest initial subsequence of top-level
statements in `domestic`'s CSS tree that contains only comments and
`@import` rules *and* that ends with an `@import` rule.
* Let `initial` be the longest initial subsequence of top-level statements in
`domestic`'s CSS tree that contains only comments and [initial rules], *and*
that ends with an initial rule.

* Otherwise, if `initial` contains a `@layer` rule `layer`:

* If `css` already contains a `@layer` rule without children, throw an
error.

* Otherwise, remove `layer` from `initial` and insert a copy of it at the
beginning of `css` after any comments.

* Insert a copy of `initial-imports` in `css` after the last `@import` rule, or
at the beginning of `css` if it doesn't contain any `@import` rules.
* Insert a copy of `initial` in `css` after the last initial rule, or at the
beginning of `css` after any comments if it doesn't contain any initial
rules.

* For each top-level statement `statement` in `domestic`'s CSS tree after
`initial-imports`:
`initial`:

* If `statement` is an `@import` rule, insert a copy of `statement` in `css`
after the last `@import` rule, or at the beginning of `css` if it doesn't
contain any `@import` rules.
* If `statement` is a `@layer` rule without children:

* If `css` already contains a `@layer` rule without children, throw an
error.

* Otherwise, insert a copy of `statement` at the beginning of `css`.

* Otherwise, If `statement` is an `@import` rule, insert a copy of
`statement` in `css` after the last initial rule, or at the beginning of
`css` if it doesn't contain any initial rules.

* Otherwise, add a copy of `statement` to the end of `css`, with any style
rules' selectors replaced with the corresponding selectors in
`new-selectors`.

* Return `css`.

[initial rules]: #initial-rule

### Extending a Selector

This algorithm takes a selector list `extendee`, a simple selector `target`, and
Expand Down

0 comments on commit 656c035

Please sign in to comment.