CSS文件顶部必须仅含空行或纯注释,随后立即声明@layer;任何非@layer语句(如@import、:root、注释含样式)将导致后续所有@layer静默失效。

必须在CSS文件最顶部声明层栈
@layer规则一旦被浏览器解析器遇到非@layer语句(哪怕是一行:root变量、一个@import或带样式的注释),后续所有@layer声明都会被硬性忽略——不是报错,是静默丢弃。这不是兼容性问题,是规范强制行为。
常见翻车点:
-
@import "reset.css"; @layer base;→@layer base完全失效 -
/* 全局主题色 */ :root { --primary: #3b82f6; } @layer components { }→@layer components不生效 - 正确写法:CSS文件开头只允许空行或纯注释(不含任何样式内容),紧接着就是
@layer reset, base, components, utilities;
@import layer()必须是顶层语句,不能嵌套
第三方库(如Ant Design、Bootstrap)默认落在「未命名顶层」,优先级高于你所有显式声明的层。想让它服从你的层级体系,必须用@import url("xxx.css") layer(framework);,且这条语句必须和@layer reset, base, ...;并列,处于CSS文件最顶层。
错误示范:
-
@layer framework { @import "antd.css"; }→ 语法非法,整条@layer块被忽略 -
@media (prefers-color-scheme: dark) { @layer dark { ... } }→@layer不能出现在条件块内 - 稳妥做法:把第三方CSS内容复制粘贴进
@layer framework { /* paste here */ },彻底规避加载时序与语法限制
层间优先级压倒选择器权重,但层内仍按老规则走
@layer只决定“哪一层先入场”,不改变层内规则的胜负逻辑。这意味着:
-
@layer utilities { .btn { color: red; } }能覆盖@layer base { #header .btn { color: blue; } },因为utilities层优先级更高 - 但
@layer utilities { .btn { color: red; } }无法覆盖同层的@layer utilities { #submit-btn { color: blue; } },因为ID选择器特异性(0,1,0,0)仍高于类选择器(0,0,1,0) - 验证方式:打开DevTools → Computed面板 → 看被划掉规则右侧的
Specificity值(如0,1,0,0)
同名层自动合并,顺序由首次声明位置决定
多个@layer utils { ... }会自动合并到同一层,但规则叠加顺序取决于它们在源码中出现的位置。这对模块化开发很实用,但也容易埋坑:
-
@layer utils { .text-sm { font-size: 0.875rem; } }和后续的@layer utils { .text-sm:hover { color: #3b82f6; } }会合并,后者生效 - 但如果另一个文件里先声明了
@layer utils { .text-sm { font-size: 0.75rem; } },而你后引入的文件又写了同名层,最终字体大小可能不是你预期的 - 建议:核心工具类统一收口在一个入口文件中定义
@layer utilities,避免分散声明
层叠层真正难的不是语法,而是重构存量样式时的分层直觉——比如该把Tailwind的@apply产物放进base还是utilities,或者要不要为暗色模式单独开一层@layer dark-mode。这些决策一旦定下,就很难回退。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











