接手别人的 CSS 代码最怕这件事——@layer 把「谁优先级高」变成明规则而不是潜规则

接手别人的 CSS 代码,最怕的不是类名看不懂——是加了 !important 也不生效。

CSS 优先级战争打到最后,所有人都在 !important 上堆 !important,直到连 !important 都不管用了。这种场景我见过太多了,团队里没人敢动老样式,新需求只能继续堆类名,CSS 文件越写越大,维护成本越滚越高。

现在 CSS 自己管这件事了——@layer 把级联表变成了目录管理。

什么是 @layer

@layer 让你把 CSS 声明组织进命名的层级,层级之间有明确的优先级顺序。

@layer base {
  h1 { color: blue; }
}
@layer components {
  .title { color: red; }
}
@layer utilities {
  .text-primary { color: green !important; }
}

执行顺序是:basecomponentsutilities,越靠后的层级优先级越高。注意,这里没有 !important 的事——优先级由层级顺序决定,不是选择器权重。

同一个层级内,选择器权重正常生效:

@layer components {
  h1 { color: blue; }
  .title { color: red; }
}

核心用法:不拆开就能控制优先级

@layer 最大的价值,是让「谁优先级高」变成显式的、而不是靠经验堆出来的。

/* 声明层级顺序 */
@layer reset, base, components, utilities;

@layer reset {
  * { margin: 0; padding: 0; }
}
@layer base {
  body { font-size: 16px; }
}
@layer components {
  .card { border: 1px solid #ccc; }
}
@layer utilities {
  .mt-4 { margin-top: 1rem; }
  .text-center { text-align: center; }
}

只要在最前面声明顺序,之后无论在哪个文件、哪个位置写 @layer components,它的优先级都在 base 之上、utilities 之下。这是 CSS 历史上第一次实现了「不看到代码也知道谁会赢」。

和 !important 的关系

@layer 不消灭 !important,而是把它变成了最后一道防线:

@layer utilities {
  .title { color: green; }
}
@layer override {
  .title { color: purple !important; }
}

如果你发现某个组件样式必须加 !important 才能覆盖,说明要么是层级顺序设计错了,要么是这个样式放错了层级。

实战:把现有 CSS 迁移进 @layer

不需要重写,只要把现有规则包进层级:

/* 旧代码保持不动 */
.card { border: 1px solid #ccc; }
.title { font-size: 1.5rem; }
.btn { padding: 0.5rem 1rem; }

/* 新代码用 @layer 包裹 */
@layer components {
  .card { border: 1px solid #ccc; }
  .title { font-size: 1.5rem; }
  .btn { padding: 0.5rem 1rem; }
}

@layer 包裹的规则优先级,和直接写的规则在同一个层级上比较。没包进任何 @layer 的样式,自动归属一个隐式最高层级——所以旧代码和新 @layer 代码混用是安全的。

调试技巧:看哪个层级赢了

Chrome DevTools 现在直接显示每个规则的所属层级:在 Elements 面板里点开 Computed 样式,找到 Cascade 面板,每个 CSS 属性会列出所有候选来源,按层级排序,灰色的就是不生效的那个。哪个层级优先级更高,一眼就看出来。

结论

@layer 解决的不是「怎么写样式」的问题,是「谁来决定谁」的问题。

以前优先级靠选择器权重、靠 !important、靠源码顺序,拼的是经验和纪律。现在只要在最前面声明一次顺序,之后往对应的层级里加规则就行了,不用再算权重,不用再堆 !important,不用再担心「这个样式改了对不对」。

团队里如果 CSS 开始变乱,第一件事不是重构选择器——是把现有的代码按 reset → base → components → utilities 的结构包进 @layer,优先级自然就清晰了。

浏览器支持:Chrome 99+、Safari 15.4+、Firefox 97+,已经是 Baseline 2022。今天就能用。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 557 阅读