CSS选择器权重

69 阅读4分钟

1. 什么是“选择器权重”

CSS 权重是浏览器用来决定 当多个 CSS 规则作用于同一个元素时,哪一个规则优先级更高、会被应用 的机制。 在 CSS 中,我们通过“选择器”来指定要改变哪些元素的样式。 但当 多个样式 同时作用在同一个元素上时,就会产生“冲突”。 例如:

p { color: blue; }
p { color: red; }

浏览器怎么知道 p 应该是蓝色还是红色呢? 这时候就靠 选择器权重 来决定——权重高的规则会“赢”,最终生效。

2. 选择器权重的生活类比

类比对象CSS 选择器类型举例权重
皇帝 🏯行内样式(HTML 元素上直接写 style)<p style="color:red">1000
大臣 👑ID 选择器#title {}100
官员 🧰类选择器 / 属性选择器 / 伪类.btn {}、[type=text]、:hover10
小兵 🪖元素选择器 / 伪元素div {}、::after1
百姓 🙋‍♂️通配符 / 继承样式* {}、继承来的0

3. 权重计算规则

浏览器内部会把一个选择器的权重拆成四个部分,通常用一个四位数表示,a-b-c-d行内样式 > ID > 类/伪类/属性 > 标签/伪元素 每种选择器对应一个“分值”,按照以下方式计算:

位数选择器类型权重
a行内样式1000
b每个 ID 选择器+100
c每个 类 / 属性 / 伪类 选择器+10
d每个 元素 / 伪元素 选择器+1
通配符(*)和继承样式+0

最后,比较数值大小即可:谁大,谁生效。这里需要注意以下几点

  • 通配符(*)和继承样式不参与权重计算
  • 这里的权重数值是为了便于计算和理解设置的数值,在浏览器实际的计算比较时:从左到右逐位比较,高位优先,即 a >> b >> c >> d

4. 常见例子

选择器权重计算(a-b-c-d)结果
div0-0-0-11
.box0-0-1-010
#main0-1-0-0100
div.box0-0-1-111
#main .box0-1-1-0110
div p strong0-0-0-33
.nav li.active a:hover0-0-3-232
<div style="color:red">1-0-0-01000(最高)

5. 特殊情况说明

1. !important 是“尚方宝剑”

不论权重多少,只要你加上 !important,它就会强制生效。 最高优先级(仅次于内联样式中的 !important

p { color: blue !important; } /* 1 */
#title { color: red; } /* 100 */

即使 #title 权重更高,!important 的蓝色仍然胜出。

2. 内联样式中的 !important

最高优先级,无法被覆盖

<p style="color: blue !important">文本</p>

即使外部有 !important 也无法覆盖

6. 权重冲突解决顺序(CSS 层叠规则)

当多个规则冲突时,浏览器按以下顺序决定优先级:

  1. !important(开发者强制)
  2. 权重(Specificity)(选择器复杂度)
  3. 源代码顺序(后写的覆盖先写的)
  4. 继承(从父元素继承的样式) 简记:important > 权重 > 顺序 > 继承

7. 实战练习

HTML:

<a href="#" style="color: yellow">链接</a>

CSS:


#main .nav a:hover { color: red; }     /* A */
body div a { color: blue; }             /* B */
a { color: green !important; }          /* C */

最终颜色是:绿色 我们先逐步分析:

  1. html中 有一个 行内样式style="color: yellow"),权重为1-0-0-0,权重值为 1000

  2. css中 设置了3条规则

    1. 规则A,#main .nav a:hover,权重为0-1-2-1,权重值为121,设置颜色为红色
    2. 规则B,body div a ,权重为0-0-0-3,权重值为 3,设置颜色为蓝色
    3. 规则C,a,权重为0-0-0-1,权重值为 1,这里需要注意 **设置了!important **,设置颜色为绿色

权重比较逻辑:

  1. 首先看有没有 !important

    1. 只有 C(绿色) 有 !important → 它直接进入最高优先级组
  2. 行内样式 vs !important

    1. !important 的优先级 > 行内样式(没有 important)
    2. 所以即使行内 style="color: yellow" 权重是 1000,也会被 C 的 !important 覆盖
  3. 其他 A、B 两条规则都没有 !important,自然也被排除

最终生效的样式: 绿色(来自 a { color: green !important; }

8. 总结

  1. !important → 优先级最高;若有多个!important,再比权重,再比加载顺序
  2. !important → 比权重(行内样式 > ID > 类/伪类/属性 > 标签/伪元素)
  3. 权重相同 → 后定义的覆盖前定义的
  4. 都没定义 → 用继承或浏览器默认样式