CSS 层(@layer)
@layer 提供了“层叠层”(Cascade Layers)机制,让你可以显式声明样式的层级顺序,从而控制不同来源、不同模块的覆盖关系,避免因选择器特异性大战而导致的维护难题。
为什么需要这个特性
- 可预测的覆盖顺序:显式定义层级顺序,避免特异性冲突
- 模块化管理:为基础样式、组件、主题、工具类分层
- 易于维护:减少
!important和高特异性选择器的依赖 - 渐进增强:可安全地添加新层而不破坏旧层
- 团队协作:约定层级,避免样式互相踩踏
核心概念解释
声明层
使用 @layer 声明层。层的顺序由第一次声明的顺序决定。
@layer reset, base, components, utilities;
定义样式
将样式放入对应层。
@layer reset {
* { margin: 0; padding: 0; box-sizing: border-box; }
}
@layer base {
body { font-family: sans-serif; color: #333; }
}
@layer components {
.button { padding: 10px 20px; border-radius: 6px; }
}
@layer utilities {
.text-center { text-align: center; }
}
未声明的层
未显式列出的层,按出现顺序排在已声 明层之后。
层与特异性
层级优先于特异性:先比较层,后比较特异性。上层样式会覆盖下层样式,即使特异性更低。
常见用法
1. 预定义层顺序
@layer reset, base, components, utilities, overrides;
2. 模块分层
@layer components.buttons {
.btn { padding: 10px 20px; }
}
@layer components.cards {
.card { border-radius: 8px; }
}
3. 主题与工具类
@layer theme {
:root { --color-primary: #007bff; }
}
@layer utilities {
.bg-primary { background-color: var(--color-primary); }
}
示例
示例 1:基础分层
@layer reset, base, components, utilities;
@layer reset {
* { margin: 0; padding: 0; box-sizing: border-box; }
}
@layer base {
body { font-family: \"Inter\", system-ui; color: #333; }
}
@layer components {
.btn { padding: 10px 20px; border-radius: 6px; }
}
@layer utilities {
.text-center { text-align: center; }
}
示例 2:覆盖顺序
@layer base, theme, overrides;
@layer base {
.btn { background: #eee; color: #333; }
}
@layer theme {
.btn { background: #007bff; color: #fff; }
}
@layer overrides {
.btn { background: #28a745; } /* 覆盖前面的层 */
}
注意事项
- 声明顺序决定层级:第一次声明的顺序生效,即使后续再次声明。
- 层优先于特异性:高层的低特异性规则可以覆盖低层的高特异性规则。
- 与 @import 配合:可在
@import中使用layer关键字导入为某层。 - 渐进增强:旧浏览器不支持
@layer时,规则会当普通 CSS 处理,需测试关键样式。 - 命名约定:团队约定层级和命名,常见:reset/base/components/utilities/theme/overrides。
- 避免滥用:层过多会增加复杂度,保持简洁。
- 与 !important:尽量用层解决覆盖,不要依赖
!important。
通过 @layer,你可以用更可控的方式管理样式的覆盖关系,减少特异性战争,使大型样式工程更易维护。