源顺序是CSS层叠规则中特异性相同时的决胜环节;<link>顺序即源顺序,因浏览器按HTML文档流从上到下解析并依次构建CSSOM,动态插入的<link>也按DOM位置排序。

加载顺序影响层叠性,是因为 source order 是 CSS 层叠(cascade)规则中明确规定的决胜环节之一——当多个规则的选择器特异性(specificity)相同、且都没有 !important 时,后出现的样式声明胜出。
为什么 <link> 顺序就是源顺序?
浏览器按 HTML 文档流从上到下解析 <head>,每个 <link rel="stylesheet"> 都会触发一次阻塞式下载与同步解析。这意味着:
- 它们不是“并行生效”,而是按 DOM 中的书写位置依次进入层叠上下文
- 即使网络层并行下载完成,CSSOM 构建仍严格遵循 HTML 中的
<link>出现顺序 - 动态插入的
<link>(如 JS 创建)也按插入时刻在 DOM 中的位置参与排序,不是按 JS 执行顺序
哪些情况下改了 <link> 顺序也没用?
顺序只在“同权重、无 !important、非内联”时起作用。常见失效场景:
-
#header .btn(权重(0,1,1,1))出现在第一个<link>,而.btn(权重(0,0,1,1))在最后一个——后者永远覆盖不了前者 - 第三方库用了
style="color: red"或!important,你的任何<link>都无法靠后置来覆盖 - 构建工具(如 Vite)把最终生成的 CSS
<link>插到了<head>最末,和你源码里写的顺序不一致——得看 DevTools 的 Network 面板确认真实 HTML
如何验证当前顺序是否真被浏览器执行?
别信编辑器里的排列,要查运行时状态:
立即学习“前端免费学习笔记(深入)”;
- 打开 DevTools → Elements 面板,展开
<head>,看<link>标签是否按预期顺序排列 - 在 Styles 面板中点击某条样式旁的文件名链接,跳转后确认它确实来自你认为“该生效”的那个文件
- 检查 Network 面板,过滤 CSS 请求,确认每个
href返回的是200状态码,且Content-Type是text/css,不是text/plain或 404 - 特别注意:路径是相对 HTML 文件位置计算的,
href="css/main.css"在/blog/post.html中请求的是/blog/css/main.css,不是项目根目录下的/css/main.css
真正容易被忽略的,是那些不改变顺序但破坏顺序效果的操作:比如在某个 CSS 文件里偷偷加了 @import,或者让 JS 把弹窗挂到 <body> 下导致 scoped 样式完全失焦——这时候调顺序只是在修表,问题在底层作用域和特异性设计上。


















