Sass 和原生 嵌套
发表于 2023 年 3 月 29 日,作者 Natalie Weizenbaum
今天发布的 Chrome 112 稳定版是第一个支持新原生 CSS 嵌套功能 的稳定浏览器。这个功能——受 Sass 嵌套的启发——增加了在纯 CSS 中嵌套样式规则的能力,甚至使用 Sass 的约定 &
来引用父 选择器。
我们 Sass HQ 的人每次看到我们的语言设计启发了 CSS 本身的改进都感到荣幸。我们很高兴看到随着更多浏览器继续推出对该 功能的支持,嵌套带来的可用性和清晰性优势将惠及更多 CSS 作者。
Sass 嵌套的未来Sass 嵌套的未来 永久链接
然而,这引发了一个重要的问题:Sass 的嵌套将会怎样?首先,我们永远不会改变现有的有效 Sass 代码,使其开始发出与广泛使用的浏览器不兼容的 CSS。这意味着即使我们决定逐步淘汰 Sass 嵌套,并改为只发出纯 CSS 嵌套,我们也不会在全球浏览器市场份额的 98% 支持原生 嵌套之前这样做。
更重要的是,原生 CSS 嵌套与 Sass 嵌套略有不兼容。这影响了三种不同的 情况
-
原生 CSS 嵌套隐式地将父选择器包装在
:is()
中,而 Sass 将其文本复制到解析后的选择器中。这意味着 :.foo, #bar { .baz { /* ... */ } }
在 Sass 中生成选择器
.foo .baz, #bar .baz
,但在原生 CSS 中生成:is(.foo, #bar) .baz
。这改变了特异性::is()
始终具有其最具体选择器的特异性,因此:is(.foo, #bar) .baz
将匹配<div class=foo> <p class=baz> </div>
在原生 CSS 中具有 1 0 1 的特异性,在 Sass 中具有 0 0 2 的特异性,即使没有元素与 ID 匹配。
-
同样因为原生 CSS 嵌套使用
:is()
,具有后代组合器的父选择器将表现 不同。.foo .bar { .green-theme & { /* ... */ } }
在 Sass 中生成选择器
.green-theme .foo .bar
,但在原生 CSS 中生成.green-theme :is(.foo .bar)
。这意味着原生 CSS 版本将 匹配<div class=foo> <div class="green-theme"> <p class=bar> </div> </div>
但 Sass 不会,因为与
.foo
匹配的元素在与.green-theme
匹配的元素之外。 -
Sass 嵌套和原生 CSS 嵌套都支持类似于
&foo
的语法,但含义不同。在 Sass 中,这会向父选择器添加后缀, 因此.foo { &-suffix { /* ... */ } }
生成选择器
.foo-suffix
。但在原生 CSS 中,这会向父选择器添加类型选择器, 因此.foo { &div { /* ... */ } }
生成选择器
div.foo
(Sass 会生成.foodiv
)。原生 CSS 嵌套没有办法像 Sass 一样向选择器添加后缀。
设计承诺设计承诺永久链接
在考虑如何处理这个新的 CSS 功能时,我们有两个重要的设计承诺需要牢记 :
-
我们致力于成为 CSS 的超集。所有受真实浏览器支持的有效 CSS 也应该在 Sass 中以相同的 语义起作用。
-
我们致力于向后兼容。我们尽可能地避免改变现有样式表的语义,如果需要这样做,我们希望给用户尽可能多的时间和资源来优雅地进行更改 。
在大多数情况下,保持 CSS 超集胜过向后兼容性。然而,嵌套是 Sass 最古老、最广泛使用的功能之一,因此我们特别不愿意改变它,尤其是在会放弃对 &-suffix
等广泛使用的功能的支持的情况下,这些功能在原生 CSS 中没有优雅的等效项。
Sass 的计划Sass 的计划 永久链接
短期内,我们不打算改变 Sass 嵌套的任何内容。Sass 只是不支持纯 CSS 嵌套,除非我们能够以完全兼容现有 Sass 行为的方式这样做。
我们将添加对解析 .css
文件中的纯 CSS 嵌套的支持。这种嵌套不会以任何方式解析;Sass 只是 按原样发出它。
长期来看,一旦:is()
被全球浏览器市场份额的 98% 支持,我们将开始将 Sass 过渡到在解析 Sass 嵌套时发出 :is()
。这将使 Sass 在前两种行为不兼容性方面表现得像 CSS 一样。我们将将其视为重大更改,并将其作为主要版本发布的一部分发布,以避免意外地破坏现有样式表。我们将尽最大努力使用Sass 迁移工具 使此过渡尽可能顺利。
我们不会放弃我们对 &-suffix
的当前行为,除非我们能想出一个更符合人体工程学的方式来表示它,并且它与 CSS 更兼容。这种行为对于现有的 Sass 用户来说太重要了,而纯 CSS 版本的好处不足以覆盖 它。