随着 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 { /* ... */ }