Update based on implementation experience

This commit is contained in:
Natalie Weizenbaum 2024-06-18 19:44:39 -07:00
parent 79799ca575
commit 4411ebae22
7 changed files with 102 additions and 20 deletions

View File

@ -0,0 +1,5 @@
## Draft 1.1
* Make sure the `@nest` rule follows the new CSS semantics.
* Produce a deprecation warning for declarations in non-top-level contexts.

View File

@ -1,6 +1,7 @@
# Interleaved Declarations: Draft 1 # Interleaved Declarations: Draft 1
*([Issue](https://github.com/sass/sass/issues/3846))* *([Issue](https://github.com/sass/sass/issues/3846),
[Changelog](interleaved-declarations.changes.md))*
## Table of Contents ## Table of Contents
@ -11,9 +12,11 @@
* [Current Keyframe Block](#current-keyframe-block) * [Current Keyframe Block](#current-keyframe-block)
* [Declarations](#declarations) * [Declarations](#declarations)
* [Semantics](#semantics) * [Semantics](#semantics)
* [Unknown At-Rules](#unknown-at-rules) * [`@nest` Rule](#nest-rule)
* [Syntax](#syntax)
* [Semantics](#semantics-1) * [Semantics](#semantics-1)
* [Deprecation Process](#deprecation-process) * [Deprecation Process](#deprecation-process)
* [`@nest` Rule](#nest-rule-1)
## Background ## Background
@ -122,27 +125,71 @@ before "Append `css` to `parent`":
[current style rule]: #current-style-rule [current style rule]: #current-style-rule
[keyframe block]: #current-keyframe-block [keyframe block]: #current-keyframe-block
## Unknown At-Rules ## `@nest` Rule
Add special semantics for the `@nest` rule. Although this rule is primarily
intended to give the CSSOM a consistent representation for interleaved
declarations and is never required to be written explicitly, it *is* valid CSS
and Sass must ensure that its use preserves the existing CSS semantics.
> This is also provides an explicit way for Sass authors to write styles that
> are consistent with CSS semantics during the deprecation period for
> interleaved declarations.
### Syntax
<x><pre>
**NestRule** ::= '@nest'¹ '{' Statements '}'
</pre></x>
1: This is case-insensitive.
### Semantics ### Semantics
Add the following to the semantics for executing an unknown at-rule `rule` after To execute a `@nest` rule `rule`:
"If `rule`'s name is 'font-face', or if its unprefixed name is 'keyframes',
append `css` to the current module's CSS":
* If `rule`'s name is case-insensitively equal to "nest", append `css` to * If there's a [current keyframe block], throw an error.
`parent`.
[current keyframe block]: #current-keyframe-block
* If there's a [current style rule], evaluate each child in `rule`'s
`Statement`s.
* Otherwise, [evaluate `rule` as an unknown at-rule] with
`InterpolatedIdentifier` "nest", no `InterpolatedValue`, and the same
`Statements`.
[evaluate `rule` as an unknown at-rule]: ../spec/at-rules/unknown.md
## Deprecation Process ## Deprecation Process
This proposal's change to the semantics of interleaved declarations is This proposal's change to the semantics of interleaved declarations is
backwards-incompatible. Before changing to the new semantics, an implementation backwards-incompatible. Before changing to the new semantics, an implementation
should have a period of deprecation in which it emits a deprecation warning for should have a period of deprecation in which it emits a deprecation warning for
a declaration whose `parent` is not the last statement in [the current module]'s a declaration whose `parent` is not the last statement in its parent without
CSS without changing the existing behavior. changing the existing behavior.
[the current module]: ../spec/spec.md#current-module
> Authors can move interleaved declarations before any nested rules to preserve > Authors can move interleaved declarations before any nested rules to preserve
> existing behavior, or nest them in `& { ... }` style rules to anticipate the > existing behavior, or nest them in `& { ... }` style rules to anticipate the
> new behavior. > new behavior.
### `@nest` Rule
During the deprecation period, use the `@nest` syntax specified above but the
following semantics:
* If there's a [current keyframe block], throw an error.
* If there's a [current style rule] `style-rule`:
* If `style-rule`'s stylesheet was [parsed as CSS], evaluate each child in
`rule`'s `Statement`s.
* Otherwise, [evaluate `rule` as a style rule with `SelectorList` "&" and the
same `Statements`.
* Otherwise, [evaluate `rule` as an unknown at-rule] with
`InterpolatedIdentifier` "nest", no `InterpolatedValue`, and the same
`Statements`.
[parsed as CSS]: ../spec/syntax.md#parsing-text-as-css

View File

@ -6,7 +6,7 @@
*/ */
export interface Deprecations { export interface Deprecations {
// START AUTOGENERATED LIST // START AUTOGENERATED LIST
// Checksum: 6e5aeefc72f4e9b4ffa0672feea75a5ad09b0282 // Checksum: 309e4f1f008f08379b824ab6094e13df2e18e187
/** /**
* Deprecation for passing a string directly to meta.call(). * Deprecation for passing a string directly to meta.call().
@ -118,7 +118,7 @@ export interface Deprecations {
* *
* This deprecation became active in Dart Sass 1.77.7. * This deprecation became active in Dart Sass 1.77.7.
*/ */
'interleaved-decls': Deprecation<'interleaved-decls'>; 'mixed-decls': Deprecation<'mixed-decls'>;
/** /**
* Deprecation for @import rules. * Deprecation for @import rules.

33
spec/at-rules/nest.md Normal file
View File

@ -0,0 +1,33 @@
# `@nest` Rule
Sass has special semantics for the `@nest` rule. Although this rule is primarily
intended to give the CSSOM a consistent representation for interleaved
declarations and is never required to be written explicitly, it *is* valid CSS
and Sass must ensure that its use preserves the existing CSS semantics.
## Syntax
<x><pre>
**NestRule** ::= '@nest'¹ '{' Statements '}'
</pre></x>
1: This is case-insensitive.
## Semantics
To execute a `@nest` rule `rule`:
* If there's a [current keyframe block], throw an error.
[current keyframe block]: ../style-rules.md#current-keyframe-block
* If there's a [current style rule], evaluate each child in `rule`'s
`Statement`s.
[current style rule]: ../style-rules.md#current-style-rule
* Otherwise, [evaluate `rule` as an unknown at-rule] with
`InterpolatedIdentifier` "nest", no `InterpolatedValue`, and the same
`Statements`.
[evaluate `rule` as an unknown at-rule]: ../at-rules/unknown.md

View File

@ -43,9 +43,6 @@ To execute an unknown at-rule `rule`:
* If `rule`'s name is "font-face", or if its [unprefixed] name is * If `rule`'s name is "font-face", or if its [unprefixed] name is
"keyframes", append `css` to [the current module]'s CSS. "keyframes", append `css` to [the current module]'s CSS.
* Otherwise, if `rule`'s name is case-insensitively equal to "nest", append
`css` to `parent`.
* Otherwise: * Otherwise:
* Append `css` to `parent`'s parent. * Append `css` to `parent`'s parent.

View File

@ -106,7 +106,7 @@ css-function-mixin:
status: active status: active
deprecated: 1.76.0 deprecated: 1.76.0
interleaved-decls: mixed-decls:
description: Declarations after or between nested rules. description: Declarations after or between nested rules.
dart-sass: dart-sass:
status: active status: active

View File

@ -29,7 +29,7 @@
### `Deprecations` ### `Deprecations`
<!-- START AUTOGENERATED LIST --> <!-- START AUTOGENERATED LIST -->
<!-- Checksum: 6e5aeefc72f4e9b4ffa0672feea75a5ad09b0282 --> <!-- Checksum: 309e4f1f008f08379b824ab6094e13df2e18e187 -->
```ts ```ts
export interface Deprecations { export interface Deprecations {
'call-string': Deprecation<'call-string'>; 'call-string': Deprecation<'call-string'>;
@ -47,7 +47,7 @@ export interface Deprecations {
'abs-percent': Deprecation<'abs-percent'>; 'abs-percent': Deprecation<'abs-percent'>;
'fs-importer-cwd': Deprecation<'fs-importer-cwd'>; 'fs-importer-cwd': Deprecation<'fs-importer-cwd'>;
'css-function-mixin': Deprecation<'css-function-mixin'>; 'css-function-mixin': Deprecation<'css-function-mixin'>;
'interleaved-decls': Deprecation<'interleaved-decls'>; 'mixed-decls': Deprecation<'mixed-decls'>;
import: Deprecation<'import'>; import: Deprecation<'import'>;
'user-authored': Deprecation<'user-authored', 'user'>; 'user-authored': Deprecation<'user-authored', 'user'>;
} }