CSS 层叠层(@layer)全攻略

244 阅读2分钟

随着 CSS 复杂度提升,样式冲突和覆盖问题越来越突出。幸运的是,现代 CSS 已经支持了“层叠层”(Cascade Layers,@layer),让我们可以像写 Sass 一样管理样式优先级。本文带你彻底掌握 @layer 的用法和最佳实践。

为什么要用 @layer?

  • 分层管理样式,避免意外覆盖
  • 团队协作更清晰,模块更独立
  • 可读性、可维护性大幅提升
  • 配合 PostCSS 插件可兼容旧浏览器

基本用法

先声明层的顺序,再分别写入各层样式:

 @layer reset, base, components, utilities;
 ​
 @layer reset {
   /* 重置样式 */
 }
 @layer base {
   /* 通用基础样式 */
 }
 @layer components {
   /* 组件样式 */
 }
 @layer utilities {
   /* 工具类 */
 }

顺序说明:越靠后优先级越高(reset < base < components < utilities)

层与特异性的优先级

  • 不同层:后声明的层优先级高
  • 同层:看选择器特异性,再看源顺序(后写的赢)
 @layer components, utilities;
 ​
 @layer components {
   .btn { background: #1677ff; }
 }
 @layer utilities {
   .btn { background: #722ed1; }
 }
 /* 结果:.btn 背景是 #722ed1,因为 utilities 层优先级高 */

!important 的表现

  • !important 依然能提升全局优先级
  • 多个 !important 冲突时,依然先看层级
 @layer components, utilities;
 ​
 @layer components { .btn { background: #1677ff !important; } }
 @layer utilities  { .btn { background: #722ed1; } }
 /* 背景为 #1677ff,因为 !important 提升优先级 */
 ​
 @layer components { .btn { background: #1677ff !important; } }
 @layer utilities  { .btn { background: #722ed1 !important; } }
 /* 背景为 #722ed1,因为 utilities 层更高 */

未分层样式的优先级

  • 未分层样式(不在任何 @layer 内)会被自动分到一个“最高优先级”的隐式层,排在所有显示层后面
  • 实际开发建议所有样式都写在 layer 内,否则容易被“漏网之鱼”覆盖
 @layer utilities {
   .btn { border-radius: 0; }
 }
 .btn { border-radius: 8px; } /* 未分层,优先级最高,最终生效 */

匿名层

  • 直接 @layer { ... } 定义匿名层,优先级按出现顺序排列
  • 只能定义一次,不能后续追加
 @layer {
   .anonymous { color: #f43f5e; }
 }

@import 与 layer

  • 可以直接把外部 CSS 归入某个具名层
  • 只能向具名层追加,匿名层不支持
 @import url("normalize.css") layer(reset);
 @import url("framework.css") layer(components);

子 layer(嵌套层)

  • 支持子层结构,优先级先比父层,再比同父下子层顺序
 @layer framework, app;
 @layer framework.base, framework.components;
 ​
 @layer framework.base { /* ... */ }
 @layer framework.components { /* ... */ }
 @layer app { /* ... */ }