@layer 必须在顶层 CSS 入口文件首行一次性声明所有层名(如 @layer reset, base, vendor, components, utilities),否则顺序错乱或失效;SCSS 中不可动态生成或嵌套声明,第三方样式需通过 @import layer() 引入。
@layer 必须在 SCSS 编译前就声明层级顺序,且不能依赖 @use 或 @import 的执行时机 —— 否则最终 CSS 里可能根本没这行代码,或者顺序错乱。
常见错误是把 @layer 当成普通规则写在局部文件里,比如:
@layer components {.btn { color: blue; }}
这看起来没问题,但问题在于:@layer components 这个命名层本身没被提前“注册”过。CSS 级联层的优先级只由首次声明 @layer 的顺序决定,后续同名层只是归入该位置 —— 而 SCSS 的 @import 或 @use 是编译时拼接,顺序不可靠。
@layer vendor、@layer components,最终输出的 CSS 可能变成 @layer components; @layer vendor;,导致业务样式反被第三方压掉@layer,但旧版构建工具(如部分 Webpack loader)会直接过滤掉不认识的 at-rule@layer 不支持在嵌套上下文里声明(比如 & { @layer foo { } }),会报语法错误正确做法是在项目最顶层的 CSS 入口文件(如 main.css 或 styles.css)顶部,用逗号分隔方式声明全部 layer:
@layer reset, base, vendor, components, utilities;
注意三点:
@charset,但不能有空行或注释挡在前面)@layer components { ... } 都会自动归入这个已定义的层,无需重复声明SCSS 本身不解析 @layer,它只是原样透传给 CSS 输出 —— 所以你不能用变量拼接层名,也不能用 @if 动态控制:
$layer-name: "components"; @layer #{$layer-name} { ... } → 编译失败@if $env == "prod" { @layer overrides { ... } } → @layer 不支持条件包裹@layer components { .card { border-radius: 8px; } },确保该文件被 import 到主入口之后@import(非 @use),需确认导入顺序;若用 @use,则必须保证模块内不提前触发样式输出(避免 @layer 出现在声明顺序之前)别把第三方 CSS 直接用 <link> 引入 HTML —— 它会落在匿名层,优先级高于所有命名层。正确方式是用 @import 并指定 layer:
@import "bootstrap/dist/css/bootstrap.min.css" layer(vendor);
或者,如果你用的是 SCSS 版本的 Bootstrap:
@import "bootstrap/scss/functions" layer(vendor);
关键点:
@import url(...) 或 @import "path" + layer(...) 语法,不能用 @use(@use 不支持 layer 绑定)css.preprocessOptions.sass.additionalData 注入全局 layer 声明@layer vendor; 和对应引入语句 —— 搜索关键词最可靠最容易被忽略的一点:@layer 只管规则生效顺序,不管选择器是否匹配。哪怕你的 @layer components 里写了 .btn { display: none },如果 HTML 里没这个 class,它就什么也不做 —— 它不是开关,是排位表。