WithCoderWithCoderWithCoder

css选择器的权重和计算规则

我们在使用CSS对网页元素定义样式时经常会遇到使用新的特殊样式覆盖它们原有的样式,然而我们怎么来保证我们新定义的元素样式能覆盖元素上原有的样式呢?这时,就会使用到CSS“权重”。在CSS中,会根据选择器的权重值来决定所定义的样式规则的次序,具有更高权重值的选择器定义的样式规则优先于具有低权重值选择器的样式规则,如果两个选择器的权重值相同,那么后定义的选择器的样式规则优先。

权重的相关概念:

    权重,是一个相对的概念,是针对某一指标而言。某一指标的权重是指该指标在整体评价中的相对重要程度。

    权重系数,是表示某一指标项在指标项系统中的重要程度,它表示在其它指标项不变的情况下,这一指标项的变化,对结果的影响。

CSS权重的理解:

    每一个css的选择器都有一个相对的重要程度值,也就是权重的值,简称“权值”;

    css通过css选择器的权重占比,来计算css选择器规则的总权值,从而确定选择器定义样式规则的优先级次序;

因此, css选择器定义的样式规则的优先级 是通过 css选择器的权重值 比较来确定的。

css选择器优先级规则:

    1. css选择器的权重值不同时,权重值高的选择器规则优先;

    2. css选择器的权重值相同时,后定义的选择器规则优先;

    3. css属性后面加 !important 时,无条件绝对优先;

权重值的计算:

那么,怎么来计算选择器的权重值呢?下面这张图介绍了权重值的计算方法:

css选择器的权重和计算规则(图1) 

我们把选择器权重值分为4个等级,每个等级代表一类选择器,每个等级的值为其所代表的选择器的个数乘以这一等级的权重值,最后把所有等级的值相加得出选择器的权重值。

划分的4个等级:

    第一等级:代表 内联样式,如 style="",权值为 1,0,0,0;

    第二等级:代表 ID选择器,如 #id="", 权值为 0,1,0,0;

    第三等级:代表 calss | 伪类 | 属性 选择器,如 .class | :hover,:link,:target | [type], 权值 0,0,1,0;

    第四等级:代表 标签 | 伪元素 选择器,如 p | ::after, ::before, ::fist-inline, ::selection, 权值 0,0,0,1;

    此外,通用选择器(*),子选择器(>)和相邻选择器(+)等选择器不在4等级之内,所以它们的权值都为 0,0,0,0;

权重值计算公式:

    权重值= 第一等级选择器*个数,第二等级选择器*个数,第三等级选择器*个数,第四等级选择器*个数;

权重值比较规则:

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

1-200325141549261.png

因此,权重值比较规则总结如下:

    1. 先从高等级进行比较,高等级相同时,再比较低等级的,以此类推;

    2. 完全相同的话,就采用 后者优先原则(也就是样式覆盖);

    3. css属性后面加 !important 时,无条件绝对优先(比内联样式还要优先);

下面,我们通过几个例子,来进行验证。

验证第一规则:

<!DOCTYPE html>
<html>

<head>
    <title>CSS选择器权重值比较规则一:先从高等级进行比较,高等级相同时,再比较低等级的,以此类推</title>
    <style type="text/css">
        /* 权重值 100 + 1 = 101 */
        #parent p {
            background-colorred;
        }

        /* 权重值 1 + 10*11 + 1 = 112 */
        div .a.b.c.d.e.f.g.h.i.j.k p {
            background-colorgreen;
        }
    </style>
</head>

<body>
    <div id="parent">
        <div class="a b c d e f g h i j k">
            <p>内容背景色为red</p>
        </div>
    </div>
</body>

</html>

如果对css权重理解不透彻的话,看到上边的例子,估计会有很大一部分人都会认为最后 p 的背景色是 green; 为什么呢? 因为理解成了错误的权值计算规则,认为第二个选择器的权重值是112 大于(>) 第一个规则的权重值101,所以 第二个样式规则 优先级高,背景色为 green;然而结果却是 背景色为 red。

这是因为id选择器的权重值高于标签和类选择器的权重值,所以也就印证了,上面所说的权重值比较规则 第一条。

验证第二规则:

<!DOCTYPE html>
<html>

<head>
    <title>CSS选择器权重值比较规则二:完全相同的话,就采用 后者优先原则(也就是样式覆盖)</title>
    <style type="text/css">
        /* 权值: 0,2,0,0; */
        #parent #child {
            background-colorred;
        }

        /* 权值: 0,2,0,0; */
        #parent #child {
            background-colorgreen;
        }
    </style>
</head>

<body>
    <div id="parent">
        <div id="child">内容背景色为green</div>
    </div>
</body>

</html>

运行的结果,内容背景色为green,所以也就印证了,上面所说的权值比较规则 第二条。

验证第三规则:

<!DOCTYPE html>
<html>

<head>
    <title>CSS选择器权重值比较规则二:css属性后面加 !important 时,无条件绝对优先(比内联样式还要优先)</title>
    <style type="text/css">
        /* !important 无条件绝对优先 */
        #parent div#child {
            background-coloryellow !important;
        }

        /* 权值: 0,2,0,1; */
        #parent div#child {
            background-colorred;
        }

        /* 权值: 0,2,0,1; */
        #parent div#child {
            background-colorgreen;
        }
    </style>
</head>

<body>
    <div id="parent">
        <!-- 添加内联样式 -->
        <div id="child" style="background-color:orange;">内容背景色为yellow</div>
    </div>
</body>

</html>

如果没有 !important 的样式规则时,内联样式的优先级是最高的,背景色为 orange;加了 !important 之后,没有任何理由的 它的优先级就最高了,背景色为 yellow;因此也就印证了,上面所说的权值比较规则 第三条。

选择器的优先级:

通过上边的分析,我们就得出了单个选择器的优先级比较:

  css属性 !important

  > 内联样式 

  > ID选择器(#id)

  > 类选择器(.class) = 伪类选择器(:hover等) = 属性选择器[type等] 

  > 元素选择器(p等) = 伪元素选择器(:after/:before/::selection等) 

  > 通用选择器(*) 

  > 继承的样式

欢迎分享交流,转载请注明出处:WithCoder » css选择器的权重和计算规则