CSS 中将出现一项新功能:@layer
。
这 来自 Miriam Suzanne,她一直在努力影响重要的 CSS 新功能。 我一直在听说这些,但突然间它就在实验性浏览器中发布了。
把这交给 Bramus 来深入研究,他写了一篇关于这个功能的精彩文章。
随着层叠层出现,我们将拥有更多工具来控制层叠。 层叠层的真正强大之处在于它在层叠中的独特位置:在选择器特异性和出现顺序之前。 正因为如此,我们不必担心其他层中使用的 CSS 的选择器特异性,也不必担心我们将 CSS 加载到这些层的顺序 - 这对于大型团队或加载第三方 CSS 时将非常有用。
Bramus Van Damme,“CSS 的未来:层叠层 (CSS@layer
)“
强调部分由我添加。
这就是关键所在:这是一项影响哪些选择器获胜的新功能。 这将需要我们重新思考 CSS 的思路,因为层叠层是决定哪些样式实际应用的全新(且强大的)部分。

我之所以说它强大,是因为“更高”的层可以在层中使用更弱的选择器,依然可以轻松击败传统上更强的选择器。
/* First layer */
@layer base-layer {
body#foo {
background: tan;
}
}
/* Higher layer, so this wins, despite selector strength */
@layer theme-layer {
body.foo {
background: #eee;
}
}
/* Careful! Unlayered styles are more powerful than layers, even if the selector is weaker */
body {
background: red;
}
由于底部 CSS 根本不在层中,因此它会获胜,即使选择器更弱。
而且您不仅限于一个层。 您可以根据自己的需要定义和使用它们。
@layer reset; /* Create 1st layer named “reset” */
@layer base; /* Create 2nd layer named “base” */
@layer theme; /* Create 3rd layer named “theme” */
@layer utilities; /* Create 4th layer named “utilities” */
/* Or, @layer reset, base, theme, utilities; */
@layer reset { /* Append to layer named “reset” */
/* ... */
}
@layer theme { /* Append to layer named “theme” */
/* ... */
}
@layer base { /* Append to layer named “base” */
/* ... */
}
@layer theme { /* Append to layer named “theme” */
/* ... */
}
真的令人难以置信。
我们将如何使用它?
我想知道一个常见的模式是否会变成……
- 对所有内容进行分层,以便优先级级别非常清晰。 也许只允许未分层的 CSS 用于超级强大的覆盖,但理想情况下,即使是这种做法也应该作为高级层进行。
- 重置作为最低层。
- 第三方内容作为中间层。
- 团队编写的任何内容作为最高层。
您不必担心在层之间留出空间(就像您在使用z-index
时可能会做的那样),因为您可以随时调整它,而无需附加任何数字。
时间会证明一切。
调试
我希望 DevTools 能非常清楚地表达层,因为当我们看到看起来更弱的选择器由于层级位置而获胜时,一段时间内肯定会有不少挠头现象。
浏览器支持
看起来 Caniuse 在这里很积极!
这些浏览器支持数据来自 Caniuse,其中包含更多详细信息。 数字表示浏览器从该版本开始支持该功能。
台式机
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
99 | 97 | 否 | 99 | 15.4 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 15.4 |
更新
这些功能非常新(截至撰写本文时),因此预计会出现波动性。 看起来在 2021 年 10 月 6 日,决定未分层的样式实际上是最强的样式,而不是最弱的样式。 我已尝试更新文章以显示这一点。
我不想无礼,但我真的看不出它的用处。
有人可以给我一个合理的例子吗?
非常感谢!
它将有助于覆盖现有样式。 假设我正在为一个大型组织开发网站,该组织使用跨越所有网站的中央 CSS。 他们可能有一个像这样的样式:
要覆盖它,我需要匹配特异性,并让我的 CSS 放在后面,或者击败特异性。 如果标记不受我的控制,并且没有其他类,那么我就没有办法了。
但是,我可以把它添加到一个层中。 分层样式优于未分层样式,因此我的覆盖只需要这样:
当然,对于像这样的单个案例,内联可能是最好的方法,但当需要更多声明时,它会更有用。
另一个例子是,如果您要导入第三方 CSS。 您可以把它们全部放在一个
@third-party
层中,然后使用一个@third-party-override
层进行微调。是的,这似乎不是一件好事。 感觉它会带来与在所有内容中添加
!important
类似的问题。另外,在这个例子中,你不能简单地重复一个类来提高特异性吗?
我认为这可能会产生负面影响,因为它会给特异性战争增加一层额外的复杂性。 我预见到第三方组件将拥有完全“分层”的样式,因为它们不想被覆盖,然后开发人员需要负责覆盖它们。
我也是这么想的。
如果您在包含它们的层之前创建了一个层来覆盖它们的层,那么您就会获胜。 除非第三方组件有办法强制先定义它们的层(也许通过 JavaScript 注入?),否则它们没有办法强制执行此问题。
现在,我可以看到 Next/Nuxt/等类似框架能够强制执行此操作,但我认为这些框架不会做太多样式调整。
您不需要先声明您的层,因此您不必担心这个问题。
如果您想覆盖一个层,只需将您的层放在它后面,就像通常的层叠覆盖一样,CSS 的名称也是由此而来。
而且,由于未分层规则在最新的草案(2021 年 10 月)中优先级更高,因此似乎会更容易。
看起来
@layer
将成为新的!important
:P我看到这里评论中的人们将它与
!important
进行比较……我认为这是一个合理的比较,因为这是我们目前最接近层叠层的工具之一。但是,我认为这也太狭隘了。 如果您的 CSS 随着时间的推移非常静态,并且您控制了它,那么层叠层可能不会带来很大的优势(尽管这还有待观察,因为它为 CSS 提供了一个新的结构方面)。
但是,如果您使用的是第三方 CSS 或内部共享的 CSS,那么层叠层允许简化这些样式(例如,看看 Bootstrap 的样式,它到处都使用
!important
),因为它们可以依赖于开发人员将自己的 CSS 放在较低的层,或者最终它们可以将自己的 CSS 放在预定义的层,并让开发人员根据需要将其放置在 CSS 层级中。我认为层叠层将消除我们自己的 CSS 和第三方 CSS 中对
!important
的需要。 它为层叠添加了另一个维度,它在宏观层面上起作用,这让我们可以使用选择器特异性和选择器顺序在微观层面上进行微调。我认为这是一个很棒的功能!
的确。
!important
的问题在于它是针对声明的,可能会出现在级联的任何上下文中,从而破坏其他特异性因素。@layer
与此大不相同。它允许您以宏观的方式在“上帝模式”下管理特异性。我们可以将项目的整个架构考虑在内,为特异性设置外部边界,但随后让各个层级的“成员”从那里开始竞争。对此非常期待。
这个 CSS 层级的东西很有趣,毫无疑问。
但是……他们到底想解决什么问题?
我不明白排序顺序。它仍然是根据声明排序顺序确定的吗?
听起来它们类似于命名空间。我们将能够在特定命名空间的范围内覆盖内容。
最新版本的 Safari Technology Preview(版本 132)将 CSS 级联层作为实验性功能(开发 → 实验性功能 → CSS 级联层)。
看起来像是
@import
,但它是内联的。从无障碍的角度来看,我想知道
@layer
将如何影响使用自定义用户样式表的人。我们离无障碍专家还很远,但我们正在思考浏览器扩展等类似的东西,并且认为从长远来看这应该是一个积极的方面,但在短期内可能需要重新编写一些脚本。将来,应该可以轻松地在更高层编写用户样式,这样您的样式始终会被应用。
“它允许您以宏观的方式在“上帝模式”下管理特异性”
说得好。
一些 SaaS 软件允许您添加自己的自定义 CSS 来“主题化”应用程序,使其位于基本 CSS 主题之上,而该主题无法删除。很多时候,它们选择的 CSS 选择器很不尽人意。
@layers
在这种情况下非常有用,您可以将其完全清除并从头开始。除非我的层级搞错了;)层级是否可以与 JavaScript 一起使用?
我认为这个特性在能够“排序”基本 CSS、重置等方面有积极的一面。
但是,如果可以在代码中的任何地方创建层级,是否意味着它将成为一个重复
z-index
功能的特性?我认为就是它了。
我从 2003 年开始编写 CSS2 样式表,但直到 2013-15 年才对 JS 有初步了解(直到 2018 年才有所进展)。
由于我在 CSS 方面的经验比 JS 多了 10-12 年,即使在我理解 JS 中的作用域之后,我也没有理解不随意将东西(某些东西、很多东西、所有东西)放在全局作用域中的重要性。
回想起来,我意识到这是因为在 CSS 样式表(我更熟悉的范式)中,所有内容(除非您将媒体查询视为准作用域)都位于全局作用域中。
因此,我以与全局作用域 CSS 相同的方式全局作用域了我的 JS,并且后来才学到了更好的方法。
但随着CSS 级联层的引入,现在确实存在一个 CSS 全局作用域:未分层样式。
因此,就像全局作用域变量在 JS 最佳实践中只出现很少一样,在未来潜在的 CSS 最佳实践中,
@layer
将被部署到任何地方,以确保全局作用域样式也出现很少。这种方法意味着,除非有充分的理由,否则不应该使用未分层的样式,而是CSS 级联层将成为大多数样式表的主流,与例如CSS 自定义属性和触摸屏媒体查询并驾齐驱。
“但是,我应该何时使用
@layer
?”(在一定程度上)类似于ES2015中引入let
和const
之后提出的“但是,我应该何时使用const
?”这个问题。只有在更深入的理解发展之后,许多 ES2015 开发人员才将这个问题重新定义为:“我什么时候不应该使用
const
?”所以也许就是它了。也许与其问我们应该何时使用级联层,不如我们全面采用
@layer
,并认识到我们任何人都可以问的更重要的一个问题是