同权重规则按源码顺序生效是因为浏览器先收集所有CSS规则,再按权重分组、同组内依源码位置排序,后定义者排尾并覆盖前者;这是层叠机制的本质,非时间偏见。

同权重规则为什么按源码顺序生效
浏览器解析 CSS 时,不会边读边渲染样式,而是先把所有规则收集完、分组排序后再应用。权重相同时,它只看这些规则在源码中出现的先后位置——靠后定义的排在队尾,最终覆盖前面的。这不是“时间偏见”,而是层叠(cascading)机制的自然结果:cascade 本意就是“逐级落下”,不是随机挑选。
哪些情况看似同权重实则不同
很多人以为 .btn 和 button.btn 权重一样,结果后者总赢,其实是没算准权重:
-
.btn是 (0,0,1,0),button.btn是 (0,0,1,1) —— 多一个元素选择器,D 位高 1,根本轮不到比顺序 -
a:hover是 (0,0,2,1),.link是 (0,0,1,0),前者多一个伪类,权重已碾压 -
#user .profile是 (0,1,1,1),#user.profile是 (0,1,1,0),前者多一个类选择器,权重更高 -
[data-id]和.class都是 (0,0,1,0),但[data-id].active就变成 (0,0,2,0)
引入顺序 ≠ 加载顺序,别被网络延迟骗了
你改了 main.css 末尾的样式却没生效,第一反应常是“是不是没加载到”?其实浏览器会等所有 CSS 解析完成才开始渲染。<link> 的 DOM 位置决定的是「解析后排序的依据」,不是「谁先下载谁先赢」:
-
<style>.nav-link { color: blue; }</style>写在<link rel="stylesheet" href="base.css">后面 → 覆盖base.css里同权重的规则 - 两个
<link>标签,theme.css在reset.css后面 →theme.css里同权重规则生效 -
@import声明虽写在<style></style>里,但实际解析晚于所有<link>→ 即使语法上“在前面”,也大概率排在队尾
怎么快速验证当前生效的是哪条规则
别猜,直接用 DevTools 的 Elements 面板看目标元素,右侧 Styles 栏里被划掉的规则,点开小箭头能看到:
立即学习“前端免费学习笔记(深入)”;
- 它被哪条规则覆盖
- 两条规则各自的权重值(比如 (0,0,1,1) vs (0,0,1,0))
- 来自哪个文件及具体行号
- 如果某规则显示 “inherited from body”,说明它是继承来的,权重为 0 —— 即使写在最后也赢不了任何指定样式
真正容易被忽略的是:权重计算不进位,也不加总;比较时从左到右逐位比,第一位不同就定胜负。哪怕你写了十个类名,只要没多 ID 或内联,就还是 (0,0,n,0),永远压不过一个 #id。


















