sass/accepted/interleaved-declarations.md
2024-07-03 17:28:18 -07:00

3.9 KiB

Interleaved Declarations: Draft 1.1

(Issue, Changelog)

Table of Contents

Background

This section is non-normative.

Historically, Sass has hoisted declarations that appear after nested rules into the original style rule. Although this doesn't match the logical ordering of the source document, it does avoid duplicating the style rule (and any other nested rules) for each set of interleaved properties.

Many years after this decision was made, the CSS Nesting Module was published by the W3C, adding native support for nesting rules within style rules using essentially the same syntax as Sass. Although initially its semantics for interleaved declarations were the same as Sass's, a later update (four days ago at time of writing) changed it to preserve the logical ordering of interleaved declarations.

Summary

This section is non-normative.

This proposal changes the behavior of declarations that appear after nested rules. Instead of being hoisted to the beginning of the parent rule, they will now be placed in their original logical order, duplicating the parent selector.

That is, the following Sass:

.a {
  color: red;
  @media screen {color: blue}
  color: green;
}

will now compile to this CSS:

.a {
  color: red;
}

@media screen {
  .a {
    color: blue;
  }
}

.a {
  color: green;
}

Definitions

Current Style Rule

Change the definition of the current style rule to:

Differences are highlighted in bold.

The current style rule is the CSS style rule that was created by the innermost execution of a style rule, @media rule, @supports rule, unknown at-rule. This may be overridden by the execution of a declaration.

Current Keyframe Block

Change the definition of the current keyframe block to:

Differences are highlighted in bold.

The current keyframe block is the CSS keyframe block that was created by the innermost execution of a style rule. This may be overridden by the execution of a declaration.

Declarations

Semantics

Add the following to the semantics for executing a declaration declaration before "Append css to parent":

  • If parent isn't the last statement in its parent:

    • Let copy by a copy of parent without any children.

    • Append copy to parent's parent.

    • Set the current style rule, keyframe block, or at-rule (according to copy's type) to copy, for the remaining duration of its previous value.

    • Set parent to copy.

Deprecation Process

This proposal's change to the semantics of interleaved declarations is backwards-incompatible. Before changing to the new semantics, an implementation should have a period of deprecation in which it emits a deprecation warning for a declaration whose parent is not the last statement in its parent without changing the existing behavior.

Authors can move interleaved declarations before any nested rules to preserve existing behavior, or nest them in & { ... } style rules to anticipate the new behavior.