@layer 未颠覆优先级规则,而是新增层序维度:先比层序、再比特异性、最后看顺序;未命名层和未分层样式属最高层,混用将导致机制静默失效。

@layer 不是“颠覆”选择器优先级计算规则,而是给它加了一个更高阶的判断维度:层序优先于特异性。浏览器在计算最终样式时,先比层,再比权重,最后看声明顺序。
层序决定胜负,特异性退居二线
传统 CSS 中,#modal .btn(权重 1-1-0)永远赢过 .btn(权重 0-1-0),无论谁写在后面。而用 @layer 后,只要把后者放进更高层,它就能直接覆盖前者——哪怕选择器更弱。
-
@layer base { #modal .btn { color: blue; } }—— 再强的权重也困在 base 层 -
@layer overrides { .btn { color: red; } }—— 再弱的选择器,只要在 overrides 层,就自动胜出 - 关键不是“改权重”,而是“换赛道”:浏览器先查这条规则属于哪一层,层序靠后 = 天然高优
@import layer() 语法比 @layer {...} 更安全
很多项目卡在第三方库无法控制的问题上。直接 @import "tailwind.css" 会把它丢进未分层区域,不受你定义的层序约束;但用 @import url(tailwind.css) layer(framework); 就能一劳永逸地把它钉进 framework 层。
- 必须用
layer()参数形式,不能写成@layer framework { @import ... }—— 后者无效,且可能被忽略 - 该语法 Chrome 99+、Firefox 97+、Safari 15.4+ 均支持,无需构建工具介入
- 检查是否生效:DevTools 的 Styles 面板里,对应规则右侧应显示「layer: framework」标识
未命名层和未分层样式是最大陷阱
你以为写了 @layer components { .btn { ... } } 就万事大吉?错。如果项目里还混着没进任何层的样式(比如普通 .btn 规则),它们默认处于最高层,会无条件覆盖所有已命名层里的同名规则。
-
@layer { .reset { margin: 0; } }是匿名层,优先级低于显式命名层,且无法被后续引用 - 所有未包裹在
@layer name { }或未通过layer()导入的 CSS,都算“unlayered”,天然高于你精心设计的层结构 - 真正难的不是写对语法,而是确保整个项目 CSS 要么全进层,要么全不进——混用等于失效
最常被忽略的一点:@layer 声明语句(如 @layer reset, base, components;)必须出现在整个样式表最顶部,前面不能有任何其他 CSS 规则,否则整套机制静默降级回传统级联逻辑,连报错都不会有。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











