CSS层叠顺序由link标签在HTML中的物理顺序决定,后引入的同权重规则覆盖先引入的;@import不改变link顺序但会阻塞加载;@layer需严格前置且第三方样式默认高于显式层,验证须依赖DevTools的Computed面板。

link 标签顺序就是层叠顺序
浏览器按 <link rel="stylesheet"> 在 HTML 中从上到下的书写顺序,逐个下载、解析、应用 CSS;后出现的 <link> 里同权重的选择器声明,会直接覆盖前面的。这不是“谁更高级”,而是“谁最后写入谁生效”。
常见错误现象:theme.css 里改了 .btn 颜色但没变 → 实际是 base.css 在它后面引入,又重写了同一规则;用 DevTools 查看计算样式时发现来源文件和预期相反 → 检查 <head> 里 <link> 的物理顺序是否颠倒。
- 重置类(如
reset.css)必须放在最前 - 框架/组件库(如
antd.css)紧随其后 - 项目基础变量、工具类(
base.css)放中间 - 主题、页面专属样式(
page.css)必须放在最后
@import 不改变外部 link 的层叠顺序
@import 是 CSS 文件内部的加载指令,它不参与 HTML 中 <link> 的层叠排序。它的优先级只取决于宿主 CSS 文件自身的引入时机 —— 如果宿主文件是第 3 个 <link>,那里面所有 @import 进来的样式,就等效于在第 3 个位置“插入内容”。
风险点很明确:@import 会阻塞后续资源下载,且嵌套层级深时,加载顺序变得不可控。比如 <style>@import "a.css";</style> 放在 <head> 中间,它既晚于前面的 <link>,又早于后面的,但自身还拖慢解析,得不偿失。
立即学习“前端免费学习笔记(深入)”;
- 禁用
<style>@import ...</style>写法 - 避免在已通过
<link>引入的 CSS 文件中大量使用@import - 构建阶段应把
@import内联展开,或改用构建工具处理依赖
@layer 声明不改变 link 物理顺序,但能收编入场时机
@layer 不是给某条规则“提权”,而是为整组规则划定一个可预测的入场批次。但它生效的前提非常苛刻:必须出现在 CSS 文件最顶部,前面只能有空行或纯注释;一旦文件开头有 @import、:root、甚至一行带分号的变量声明,整条 @layer 就被硬性忽略。
更关键的是:第三方 CSS(比如直接 <link href="antd.css">)默认落在“未命名顶层”,天然高于你写的任何显式 @layer。所以即使你写了 @layer custom { .my-btn { color: red; } },也盖不过 Ant Design 的 .ant-btn —— 因为后者不在任何层里,且选择器特异性(0,0,2,0)本来就比你的(0,0,1,0)高。
- 第三方样式必须显式收编:
@import "antd.css" layer(framework); - 或者把第三方 CSS 内容复制进
@layer framework { }块内 -
@layer内部仍按传统特异性规则决胜负,不是进了层就自动赢
DevTools 里怎么看谁真正赢了
打开浏览器开发者工具,选中元素,在 Computed 面板里找对应属性,被划掉的规则右侧会标出 Specificity 值(如 0,0,2,0),点击该规则还能跳转到来源文件和行号。这是唯一可信的验证方式。
不要凭 <link> 顺序猜,也不要只看 Styles 面板里哪条“显示出来”——那里只展示当前生效的,不反映覆盖链。容易被忽略的点是:同一选择器在多个文件中重复出现时,顺序决定覆盖,但若特异性不同,高特异性哪怕在第一个 <link> 里,也能赢过低特异性但在最后一个里的规则。



















