Skip to content

三、CSS 选择器优先级

TIP

  • 当多个 css 规则集同时作用于同一个 HTML 标签时,不同属性会叠加,但相同属性会发生覆盖。

  • 在发生覆盖时

    • 如果多个选择器优先级一样,则以写在后面的选择器中的属性为主。

    • 如果选择器优先级不一样,则浏览器需要判断 选择器的优先级,然后以选择器优先级最高那个选择器中的属性值为主,从而在该元素上应用这些属性值。

1、单个选择器类型的权重

TIP

  • 我们前面讲过基础选择器类型的优先级,从高到低为:id 选择器 > class 选择器 > 标签选择器 > 通配符选择器。

  • 但我们学过的选择器类型远不止上面这 4 种,那这些选择器都放在一起,谁的优先级会更高一些呢?

  • 本质上,不同类型的选择器有不同的分数值,分数值越高,选择器的权重越高,具体如下表。

选择器的类型 实例 选择器权重 等级
!important div{ color:red!important; } 无穷大 特级
行内样式 (style 属性中样式) style='color:red;' 1000 第一等级
id 选择器 #id 0100 第二等级
class、伪类、属性选择器 .box:hover[type='text'] 0010 第三等级
标签选择器、伪元素选择器 div::after::before 0001 第四等级
通配符、子选择器、相邻选择器等 *>+~ 0000 第五等级
继承的样式 0000

提示:

  • 通配符 权重实际是要大于继承的样式的

2、复杂选择器优先级计算

TIP

  • 优先级就是分配给指定的 CSS 声明的一个权重

  • 选择器的优先级是由选择器中的每一种 选择器类型的数值(权值)相加的最终结果来决定。(数值越大,代表选择器的优先级越高)。

以下是复杂选择器的权重计算规则

  • 这里要对照我们前面讲过的单个选择器类型的选择器权重来计算

  • 这里的行内样式 <p style="color: red"></p>并不是选择器,但我们把他放在一起,是因为他会影响我们最终的结果

选择器 千位 百位 十位 个位 优先级
行内样式
如:<p style="color:red"></p>
1 0 0 0 1000
div p 0 0 0 2 0002
#box div p 0 1 0 2 0102
.box .item h3 0 0 2 1 0021
.box:hover p 0 0 2 1 0021

案例 1:

鼠标放在 p 标签上,文字会变成红色吗?

<style>
  /* 优先级 0011 */
  p:hover {
    color: red;
  }
  /* 优先级 0011 */
  .box p {
    color: blue;
  }
  /*
  两选择器优先级相同,都是0011,则以写在后面的为主,相同属性发生覆盖。
  则最终效果为 blue蓝色,鼠标滑上去文字并不会变色
  */
</style>
<body>
  <div class="box">
    <p>文本内容</p>
  </div>
</body>

答:

鼠标滑动到 p 上面,文字并不会变成红色

案例 2:

以下案例中的 p 标签的最终显示效果怎样的?

<style>
  /* 优先级:100 */
  #title {
    color: red; /*生效*/
  }
  /* 优先级:20 */
  .box .title {
    /* 不生效,以#title为主 */
    color: blue;
  }
  /* 优先级:10 */
  .title {
    /* 生效 */
    font-size: 16px;
  }
  /* 优先级:2 */
  div p {
    /* 不生效,以.title中为主 */
    font-size: 40px;
  }
</style>
<body>
  <div class="box">
    <p id="title" class="title">p中内容</p>
  </div>
</body>

渲染效果: ![[Pasted image 20260226171736.png]] **案例 3:

以下案例中,p 标签中的文字最终是以什么颜色显示?

<style>
  /* 单个选择器类型优先级从高到低:id  > class > 标签 */
  /* 优先级 0201 */
  #box1 #box2 p {
    color: red;
  }
  /* 优先级 0212  三个中优先级最高,则以他为主 */
  #box1 div.box2 #box3 p {
    color: green;
  }
  /* 优先级 0031 */
  .box1 .box2 .box3 p {
    color: blue;
  }
</style>
<body>
  <div class="box1" id="box1">
    <div class="box2" id="box2">
      <div class="box3" id="box3">
        <p>我是一个段落标签</p>
      </div>
    </div>
  </div>
</body>

![[Pasted image 20260226171909.png]]

2.1、优先级计算注意事项

TIP

  • 在进行选择器权重计算时不允许进位

  • 例如,20 个类选择器仅仅意味着 20 个十位,而不能视为 两个百位,也就是说,无论多少个类选择器的权重叠加,都不会超过一个 ID 选择器。

#box {
}
/* 以下20个类选择器的权重 都是要比 #box 选择器的权重要低 */
.item.item2......item20 {
}

2.2、优先级计算技巧

TIP

在比较选择器优先级时,如果都要向前面那样计算出每个选择器优先级权重值,再来决定优先级高低,那肯定相当麻烦。

这里推荐一个又快有好的计算优先级的方法

先比较高位,再比较低位。

先比较 id 选择器,再比较 class、伪类、属性选择器选择器,再比较 标签、伪元素选择器选择器

  • 如果 id 选择器个数不一样,则以 id 选择器个数多的为主;如果个数一样,则再比较 class、伪类、属性选择器加起的个数;

  • 如果 class 选择器个数不一样,则以 clas 选择器多的为主;如果个数一样,则往后再比较标签 、伪元素选择器加起来的个数,原理和 id 选择器比较原而一样,依此类推。

/*
先比较两者中的 id选择器个数,则 第一个选择器中 id个数为1,第二个为0 ,则以#box中的样式为主
*/

#box {
}
.item p {
}

/*
两者中 id个数一样,则比较class类,类也一样为0 ,则比较标签
标签个数也一样,则两都优先给一样。优先级一样,谁在后面听谁的。
*/

#box p {
}
div p#title {
}

/*
id个数都为 0 ,则比较 class类, 第一个有2个class,第二个只有一个class,所以第一个选择器优先级要高 ,以第一个为主
*/

.box .item p {
}
.box div p {
}

3、!important 提升权重

TIP

  • 当在一个样式声明中使用一个 !important 规则时,此声明将覆盖任何其他声明,包括行内样式。

  • 虽然,从技术上讲,!important 与优先级无关,但它与最终的结果直接相关

<style>
  div {
    color: red !important;
  }
  #box {
    color: orange;
  }
</style>
<body>
  <div style="color: blue">文本内容</div>
</body>

渲染效果: ![[Pasted image 20260226172001.png]]

注:

  • 只要 css 声明属性值后面带 !important,就一定以他为主。

慎用 !important

  • 不过我们要慎用 !important,因为这会带来样式的冲突。后面某个地方,需要重写这个样式时,会发现根本无效。一般你在利用第三方组件或 css 框架时,如果不能重写样式,那将会失去很多色彩。

  • 在某些情况下是可以用的,比如在之前学的自定义字体时,font-family 属性后面可以加 !important 关键字。

4、CSS 选择器冲突解决流程

TIP

通过右击审查元素,找到有哪些选择器在控制当前标签元素的样式,然后按以下步骤来分析:

1、是否找不到自己写的 css 选择器,如果是,则肯定是选择器单词写错造成。

2、看元素要生效的样式是否被其它样式覆盖了,如果是,看下是否是因为

  • 属性后面书写了 important 关键词,如果是,去掉 important

  • 元素是否有添加行内样式,被行内样式覆盖了,如果是,则将行内样式改为内联或外链样式

  • 选择器优先级问题造成的覆盖,还是因为书写顺序问题造成的覆盖。

    • 如果是优先级,则提升优先级。

    • 如果是书写顺序,则调整书写顺序


四、测试题

TIP

深入浅出 CSS 三大特性,完成以下测试题

1、看代码,回答以下三个问题

TIP

  • 鼠标滑动到 span 上时,span 中的文字有没有放大和变红?为什么?

  • 如果鼠标滑动到 span 上时,想实现文字变红,如何修改代码,达到效果?

  • span 标签最终的呈现效果是什么?为什么是这样的?

<style>
  .box {
    font-style: italic;
  }
  .box p span {
    color: blue;
  }
  span:hover {
    color: red;
    font-size: 30px;
  }
</style>
<body>
  <div class="box">
    <p><span>我是span中内容</span></p>
  </div>
</body>

▼ 点击查看答案解析

1、鼠标滑动到 span 上时,span 中的文字有没有放大和变红?为什么?

  • 答:不会变红,因为 span:hover; 的优先级低于 .box p span,所以最终 color: blue;

2、如果鼠标滑动到 span 上时,想实现文字变红,如何修改代码,达到效果?

  • 答:把 span:hover 选择器,改成 p span:hover { } 提高选择器的优先级

3、span 标签最终的呈现效果是什么?为什么是这样的?

  • 答:span 最终以 16px、蓝色、斜体 来呈现,当鼠标滑上去时,文字会变大到 30px

解读

所以 span 中文字最终以 16px 蓝色 斜体 来呈现

  • .box p span 中没有 font-style 属性,所以其默认的 font-style 属性是继承其祖先元素 div 的 font-style:italic;

  • .box p span 中没有定义 font-size 则会继承 body 的 font-size:16px

  • .box p span 中定义了 color:blue;

当鼠标滑上去时,文字会变大到 30px

  • span:hover 中的 color 属性并不会生效,因为 span:hover 的优先级低于 .box p span

  • span:hover 中的 font-size:30px 是生效的,因为在 .box p span 中并没有声明 font-size 属性。

2、以下 span 中文字的颜色是?

<style>
  .col {
    color: red;
  }
  div p span {
    color: blue;
  }
</style>
<body>
  <div>
    <p><span>span标签的文字颜色</span></p>
  </div>
</body>

▼ 点击查看答案解析

.col 并没有作用于 span 标签,所以控制 span 标签的字体颜色为 color:blue; 蓝色

3、鼠标滑动到 a 标签,a 标签中文字能不能变成黄色

<style>
  /* 12 */
  li a:hover {
    color: yellow;
  }
  /* 12 */
  .list li a {
    color: orange;
  }
</style>
<body>
  <ul class="list">
    <li><a href="">艾编程</a></li>
  </ul>
</body>

▼ 点击查看答案解析

li a:hover 与 .list li a 的优先级一样,优先级一样,以写在后面的为主,则鼠标滑上去,文字不会变成黄色

4、以下 li 中和 a 中的文字颜色分别?

<style>
  /* 2 */
  ul li {
    color: red;
  }
  /* 2 */
  ul > li {
    color: orange;
  }
</style>
<body>
  <ul class="list">
    <li>点击进入<a href="">艾编程</a></li>
  </ul>
</body>

▼ 点击查看答案解析

ul li 和 ul > li 的优先级是一样的,优先级一样,以写在后面的为主,则 li 最终的效果为橘黄色

五、本章重难点总结

TIP

  • 关于继承性所讲内容都是重点,一定要全部掌握

  • 掌握层叠性的两大特性:叠加 和 覆盖原则

  • 掌握 css 单个选择器类型的权重

  • 掌握复杂选择器权重值的计算

  • 掌握如何解决 css 冲突问题