scss编译顺序严格按源码中ast节点位置线性输出,嵌套不改变顺序,但&展开生成同级规则、@import内联插入、html中link位置共同决定最终层叠效果。

SCSS 编译出的 CSS 顺序直接影响最终层叠结果,不是因为编译器“乱排”,而是它严格按源码中规则在 AST 中的**节点位置**输出——而这个位置,直接决定了浏览器解析时的先后顺序。
SCSS 嵌套与 & 如何改变输出顺序
嵌套本身不打乱顺序,但 & 的展开会生成新层级的独立规则,它们在 AST 中是同级兄弟节点,而非父子关系:
-
.card { p { color: red; } }→ 输出为.card p { color: red; },位置由.card块在源码中的顺序决定 -
.btn { &--primary { color: blue; } &.is-active { opacity: .8; } }→ 输出两个并列规则:.btn--primary和.btn.is-active,谁写在前面,谁就先出现在 CSS 文件里 - 如果在 mixin 中多次
@include同一段带&的嵌套,每次调用都会插入一个新节点,顺序取决于@include出现的位置,不是 mixin 定义处
为什么 @import 在 SCSS 里特别危险
SCSS 的 @import 不是“合并文件”,而是把被导入内容**内联插入当前文件对应位置**。一旦你在一个已通过 <link> 引入的 SCSS 编译产物中再用 @import,就等于把另一份样式“塞进中间”:
- 假设
main.scss先@import "bootstrap",再@import "custom",编译后bootstrap规则一定在前 - 但如果
custom.scss里又@import "theme",那theme就插进了custom规则中间,可能打断你预设的覆盖逻辑 - 更糟的是:Vite/Webpack 默认把所有
@import提前解析,但某些 loader 版本下,@import若不在文件顶部(比如写了注释或空行),会被忽略或报错@import must be in root node
SCSS 编译顺序 vs HTML 中 CSS 加载顺序
两者必须对齐,否则白调权重:
- SCSS 编译后生成一个
app.css,它在 HTML 中的加载位置(<link href="app.css">放在哪)才是浏览器真正看到的“先后” - 哪怕你在 SCSS 里把自定义样式写在最后,如果
app.css被<link>放在bootstrap.css前面,你的规则照样被覆盖 - 验证方法:打开 DevTools → Elements → 看目标元素上生效的样式来自哪个文件,再点开该文件,确认那条规则是否真出现在 CSS 文件靠后位置
最常被忽略的一点:SCSS 编译器从不“优化”顺序,也不会把高权重规则往后推;它只做一件事——把 AST 节点线性扁平化输出。你写的顺序,就是浏览器拿到的顺序,也就是最终层叠的顺序。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











