CSS选择器的“权重”指specificity(特异性),是a,b,c,d四元组整数,不进位;a为内联样式、b为ID数、c为类/属性/伪类数、d为元素/伪元素数,用于决定样式生效顺序。

什么是CSS选择器的“权重”而不是“优先级”
很多人说“CSS优先级”,但规范里实际用的是 specificity(特异性),它是一套可计算的权重规则,不是“谁写在后面就赢了”的简单逻辑。浏览器按这个数值决定哪个声明生效,和顺序无关——除非权重完全相同,才轮到层叠顺序(source order)起作用。
权重不是百分比、不是布尔值,而是一个由四部分组成的“地址式”整数: a,b,c,d。它不进位,比如 1,0,0,0 永远大于 0,99,99,99。
权重四元组 a,b,c,d 怎么算
每类选择器对应一个位置:
-
a:内联样式(style="..."),只在此处计 1,其他地方为 0 -
b:ID 选择器个数(如#header) -
c:类名(.btn)、属性选择器([type="submit"])、伪类(:hover、:nth-child(2))个数 -
d:元素名(div、p)和伪元素(::before)个数
例如:
立即学习“前端免费学习笔记(深入)”;
.nav ul li:first-child a[title]::after {
color: red;
}拆解:0,0,3,4 —— 0 个 inline,0 个 ID,3 个类/属性/伪类(.nav、:first-child、a[title]),4 个元素/伪元素(ul、li、a、::after)。
常见误判场景与陷阱
这些地方最容易算错或被忽略:
-
:not()本身不增加权重,但它的参数要计入 ——div:not(.active)权重是0,0,1,1(.active贡献 c=1,div贡献 d=1) -
*(通配符)权重为0,0,0,0,但它会匹配所有元素,可能意外提升后续组合器的匹配范围 - 伪类
:is()、:where()、:has()的权重取其内部选择器中**最高者** ——:is(h1, .title, #main)按 ID 算,权重为0,1,0,0 - 继承来的样式(如父元素设置的
color)权重恒为0,0,0,0,永远低于任何直接匹配的选择器
怎么快速验证和调试权重
别靠心算。Chrome / Firefox 开发者工具里,选中元素后,在 Styles 面板中,被划掉的声明就是被更高权重覆盖的;悬停在未被划掉的属性上,会显示该规则的 specificity 值(如 0,1,1,1)。
如果需要手动比对,推荐用在线计算器,比如 specificity.keegan.st,粘贴选择器就能出结果。注意:它不支持实验性语法(如 :has() 在旧版可能报错),需确认浏览器兼容状态。
真正麻烦的不是计算本身,而是嵌套组件中多个 !important、CSS-in-JS 的动态 class、Shadow DOM 的样式隔离边界 —— 这些会让权重分析变成跨上下文问题,得结合 getComputedStyle() 和 computed 样式面板交叉验证。










