【前端基础系列】CSS篇-选择器的优先级

本文详细解释了前端面试中常见的CSS选择器优先级问题,包括权重计算规则,如何处理多重样式设置,以及!important的作用和避免使用的重要原则。通过实例演示了权重比较和!important的例外情况。
摘要由CSDN通过智能技术生成

在前端面试中,经常会遇到CSS选择器的问题三连:

  1. 说一下CSS的选择器有哪些

  2. 优先级是怎样的

  3. 权重计算方式

我们在上一篇 【前端基础系列】CSS篇-常用选择器介绍[1] 中已经对问题1进行了详细的解答,今天就来给大家介绍选择器的优先级和权重计算方式。

优先级是什么?有什么用?

先提出一个问题:如果一个元素通过多种方式设置了字体大小,那么浏览器在最后渲染时会使用哪个属性值呢?

其实,浏览器会通过优先级来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。

换种说法,优先级就是分配给指定的 CSS 声明的一个权重,它由 匹配的选择器 中的 每一种选择器类型的数值 决定。

总结一下:

  • 权重决定了你css规则怎样被浏览器解析直到生效,css权重关系到你的css规则是怎样显示的。

  • 当很多的样式被应用到某一个元素上时,权重决定哪种样式生效。

  • 每个选择器都有自己的权重。你的每条css规则,都包含一个权重级别。 这个级别是由不同的选择器加权计算的,通过权重,不同的样式最终会作用到你的网页中 。

  • 如果两个选择器同时作用到一个元素上,权重高者生效。

权重的计算规则

接着介绍权重的计算规则:

  • 第一优先级:!important会覆盖页面内任何位置的元素样式

  • 内联样式,如style="color: green",权值为1000

  • ID选择器,如#app,权值为0100

  • 类、伪类、属性选择器,如.foo, :first-child, div[class="foo"],权值为0010

  • 标签、伪元素选择器,如div::first-line,权值为0001

  • 通配符、子类选择器、兄弟选择器,如*, >, +,权值为0000

  • 继承的样式没有权值

权值计算公式:

权值 = 第一等级选择器 x 个数第二等级选择器 x 个数第三等级选择器 x 个数第四等级选择器 x 个数

比如:

选择器千位百位十位个位优先级
h100010001
h1 + p::first-letter00030003
li > a[href*="en-US"] > .inline-warning00220022
#identifier01000100
内联样式10001000

权重的比较规则

当两个权值进行比较的时候,是从高到低逐级将等级位上的权重值(如 权值 1,0,0,0 对应--> 第一等级权重值,第二等级权重值,第三等级权重值,第四等级权重值)来进行比较的,而不是简单的 1000个数 + 100个数 + 10个数 + 1个数 的总和来进行比较的,换句话说,低等级的选择器,个数再多也不会越等级超过高等级的选择器的优先级的。

下面通过几个例子进行比较规则的说明。

示例一

假设下面样式都作用于同一个节点元素span,判断下面哪个样式会生效

body#god div.dad span.son {width: 200px;}
body#god span#test {width: 250px;}

比较规则说明:

  • 先比较高权重位,即第一个样式的高权重为 #god = 100

  • 第二个样式的高权重为 #god + #text = 200

  • 100 < 200

  • 所以最终计算结果是取 width: 250px;

  • 若两个样式的高权重数量一样的话,则需要比较下一较高权重!

示例二

<style type="text/css">
     #parent p { background-color: red;  }
      div .a.b.c.d.e.f.g.h.i.j.k p{ background-color: green;  
</style>
......
<div id="parent">
     <div class="a b c d e f g h i j k">
         <p>xxxx</p>
     </div>
</div>


如果按照相加的错误方法,如果按照相加的规则的话,上述例子会为:

  qz1 = 100 + 1 = 101
  qz2 = 1 + 10*11 + 1 = 112
  qz1 < qz2

这样得出结论:第二条样式优先级高,背景色为 green

但结果却是 red,这也证明了权重是按优先级进行比较的。

总结下比较规则:

  • 1000 > 0100,从左向右逐个比较,前一级相等才能往后比较

  • 无论是行内样式、内部样式还是外部样式,都是按照以上提到的权重方式进行比较。面试的时候遇到优先级比较,如果答案是:行内>id>class>元素(标签),我们以为给了能令面试官满意的答案,其实不然,比如对同一个元素操作,在权重相等的情况下,后面的样式会覆盖前面的,这样我们给出来的答案就不成立了

  • 权重相同的情况下,位于后面的样式会覆盖前面的样式

  • 通配符、子选择器、兄弟选择器,虽然权重为0000,但是优先于继承的样式

!important 例外规则

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

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

使用 !important 是一个坏习惯,应该尽量避免,因为这破坏了样式表中的固有的级联规则,使得调试找bug变得更加困难了。

当两条相互冲突的带有 !important 规则的声明被应用到相同的元素上时,拥有更大优先级的声明将会被采用。

一些经验法则:

  • 一定要优先考虑使用样式规则的优先级来解决问题而不是 !important

  • 只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important

  • 永远不要在你的插件中使用 !important

  • 永远不要在全站范围的 CSS 代码中使用 !important

最后,我们再来看个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            font-size: 24px;
        }
        .main {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        p {color: yellowgreen} 
        .para {color: red} 
        .inner p {color: pink} 
        .main p[class*="para"] {color: rgb(0, 255, 115)}  
        .main p[class="para1"] {color:teal} 
        div.main p[class="para2"]{color: blueviolet;} 
        .inner p:nth-child(4) {color: cornflowerblue !important;} 
    </style>
</head>
<body>
    <div class="main">
        <div id="app" class="inner" >
            <p style="color: red;">我是红色的,内联样式生效</p>
            <p class="para1">离离原上草,</p>
            <p class="para2">一岁一枯荣。</p>
            <p class="para3">野火烧不尽,</p>
            <p class="para4">春风吹又生。</p>
        </div>
    </div>
</body>
</html>

样式呈现的效果如下:

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值