浏览器按特异性(a,b,c,d)四元组严格计算优先级,权重高者胜出,与加载顺序无关;第三方库依赖多类组合、动态注入或作用域隔离实现高优先级,仅调换link顺序无法解决。

样式优先级“错乱”不是随机发生的,而是浏览器严格按规则执行后的确定性结果:后加载的同权重样式覆盖前面的,但一旦选择器权重不同,顺序就失效了。
为什么 link 顺序调对了,样式还是被覆盖?
顺序只是影响层叠(cascade)的一个条件,真正起决定作用的是特异性(specificity)。比如:
-
#header .nav a权重是 (0,1,1,1),哪怕它在第一个link里,也会压过后面.nav a(权重 (0,0,1,1)) -
style="color: red"是内联样式,权重 (1,0,0,0),任何外部 CSS 都盖不住它 -
:where(.btn)权重为 0,再往后放也赢不了一个普通.btn
所以光调 link 顺序没用——得看谁的括号 (a,b,c,d) 更大。
为什么第三方库的样式总“赢”过你的?
它们不是靠顺序,是靠高权重写法和侵入式注入:
立即学习“前端免费学习笔记(深入)”;
- Ant Design 大量使用
.ant-btn-primary这类多类组合,权重天然高于你写的.btn - Element Plus 的弹窗可能挂到
body下,而你的 scoped 样式只作用于组件内部 DOM,根本匹配不到 - 某些 UI 库会用 JS 动态加
style标签或内联style,直接跳过 CSS 文件顺序逻辑
这时不是顺序错了,是你没打到它的作用域里。
为什么本地看着好,构建后就失效?
构建工具会悄悄改写最终 HTML 或 CSS 加载时机:
- Vite 的
css.preprocessorOptions插件可能把生成的 CSSlink插到head最末,不管你在源码里怎么排 - Webpack 的
MiniCssExtractPlugin按 JSimport顺序合并 CSS,和 HTML 里的link位置无关 -
@import在 CSS 文件里出现的位置,才决定它实际生效顺序,不是它物理文件的位置
务必打开 DevTools 的 Network 面板,看最终 HTML 里 link 的真实顺序,而不是你编辑器里的源码。
真正难处理的从来不是“哪个文件该放前面”,而是当 .modal 被 JS 挂到 body、var(--primary) 在 variables.css 之后才加载、:is() 把权重降成 0 时,你还得让样式链保持语义连贯——这已经超出顺序控制的范畴了。


















