一篇文章带你初步了解—CSS特指度

CSS特指度

说明

这篇博客在在两台电脑上分别完成的,故而有些截图是Firefox,有些是Chrome,有些改动了浏览器的用户样式表,有些没改,但不会影响阅读,特此说明,勿怪。

CSS选择器

单个CSS选择器

css选择器决定css样式能渲染到对应的元素上。

元素选择器:

Class选择器:

ID选择器:

多个CSS选择器

浏览器在处理单独的id、class和元素选择器时如何渲染的问题很好理解,但要在两种甚至三种不同选择器同时作用于相同的元素的情况下,浏览器又该如何渲染呢?

比如3个选择器作用在同一个元素身上的例子:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>ICE计算公式</title>
        <style type="text/css">
            #title {
                color : blue;
            }
            .red {
                color : red;
            }
            p {
                color : brown;
            }
        </style>
    </head>
    <body>
        <p id="title" class="red">这是标题</p>
    </body>
</html>

得出结果:

当3个不同的选择器(ID、Class、元素)同时作用于同一元素上时,浏览器渲染时选择的样式为ID选择器声明的样式,这是因为ID选择器的特指度高于Class选择器,而Class选择器的特指度高于元素选择器......

那么应该怎么计算每个选择器特指度,要解决这个问题,不得不提到ICE计算公式:ID-Class-Element。

ICE计算公式

关于ICE计算公式错误的理解

注:我在过去很长一段时间都是按照这种错误的思想来理解ICE计算公式的,务必注意。

关于ICE计算公式,经常看到这样的说法(这是错误的):

!important ID Class Element
特指度 1000 100 10 1

Element特指度为1,class特指度为10,ID特指度为100,!important为1000。

如果按照这样理解,是不是可以说11个class的特指度为10 * 11 === 110,它是肯定比1个Id的特指度要大的,但在我实践后,我发现不能这样去理解,就比如下面的例子:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>11个class是否比1个ID特指度大</title>
        <style type="text/css">
            #id {
                color : green;
            }
            .class1.class2.class3.class4.class5.class6.class7.class8.class9.class10.class11 {
                color: red;
            }
        </style>
    </head>
    <body>
        <p id="id" class="class1 class2 class3 class4 class5 class6 class7 class8 class9 class10 class11">p标签</p>
    </body>
</html>

如果按照class特指度为10、id为100的逻辑来理解,110 大于 100,最后p标签的color属性值应该为red,但是实际情况却是:

标签的color属性值为green。造成这样结果的原因是因为不管有多少个class选择器,Id选择器的特指度就是比class选择器的特指度大。就好比奥运会排名,先比较金牌,金牌数量多者排前面,数量少者排后面,在出现金牌数量相同时才会以银牌的数量来比较。Id选择器就好比金牌,而class选择器就好比银牌。当Id选择器数量不一致时,后续操作压根就不会去比较class选择器,所以class选择器的数量再多,也是无效的。

不同选择器对应的特指度

选择器共有:

  1. ID选择器
  2. Class选择器
  3. 元素选择器
  4. 属性选择器
  5. 伪类选择器
  6. 伪元素选择器

ID选择器

\(\color{#FF3030}{Selector Specificity: (1, 0, 0)}\)

#title {
color : blue;
}

Class选择器

\(\color{#FF3030}{Selector Specificity: (0, 1, 0)}\)

.red {
color : red;
}

元素选择器

\(\color{#FF3030}{Selector Specificity: (0, 0, 1)}\)

p {
color : brown;
}

属性选择器

\(\color{#FF3030}{Selector Specificity: (0, 1, 0)}\)

[id="title"] {
    color : black;
}

伪类选择器

\(\color{#FF3030}{Selector Specificity: (0, 1, 0)}\)

注意:p:hover的特指度为 (0, 1, 1),因为它包含了元素选择器和伪类选择器

p:hover {
color: #FF00FF
}

伪元素选择器

\(\color{#FF3030}{Selector Specificity: (0, 0, 1)}\)

注意:p::after的特指度为 (0, 0, 2),因为它包含了元素选择器和伪元素选择器

p::after {
    content: "元";
}

代码:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>6种选择器的特指度</title>
        <style type="text/css">
            #title {
                color : blue;
            }
            .red {
                color : red;
            }
            p {
                color : brown;
            }
            [id="title"] {
                color : black;
            }
            p:hover {
                color: yellow;
            }
            p::after {
                content: "元";
            }
        </style>
    </head>
    <body>
        <p id="title" class="red">100</p>
    </body>
</html>

其余还有组合选择器、分组选择器、上下文选择器、子元素选择器、相邻兄弟选择器、后续兄弟选择器,但是这几种更像是选择器的组合,它们也都是由上述6种选择器 \(\color{#FF3030}{(ID选择器、Class选择器、元素选择器、属性选择器、伪类选择器、伪元素选择器)}\)组合而成,所以它们的特指度由组成它们的选择器的特指度相加即可获得。

比如:

组合选择符

\(\color{#FF3030}{Selector Specificity: (0, 2, 0)}\)

注意:此处是对Class属性中同时含有red和indigo两个值的元素进行声明,它的特指度为(0, 2, 0)

.red.indigo {
    color : brown;
}

分组选择符

\(\color{#FF3030}{Selector Specificity: (0, 0, 1)}\)

注意:此处是对p、em、strong3个元素分别进行声明,而它们3个的特指度都为(0, 0, 1)

p , em , strong {
    color : red;
}

上下文选择符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此处是对被包含在p元素中的em元素(\(\color{#FF3030}{此时的em元素可以为p元素的子孙元素}\))进行声明,它的特指度为(0, 0, 2)

p em {
    color : red;
}

子元素选择符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此处是对被包含在p元素中的em元素(\(\color{#FF3030}{此时的em元素只能为p元素的子元素}\))进行声明,它的特指度为(0, 0, 2)

p > em {
    color : green;
}

相邻兄弟选择符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此处是对与p元素拥有相同父元素的em元素(\(\color{#FF3030}{此时的em元素必须紧跟在p元素的后面}\))进行声明,它的特指度为(0, 0, 2)

p + em {
    color : red;
}

一般兄弟选择符

\(\color{#FF3030}{Selector Specificity: (0, 0, 2)}\)

注意:此处是对与p元素拥有相同父元素的em元素(\(\color{#FF3030}{此时的em元素必须在p元素的后面,但不一定紧跟}\))进行声明,它的特指度为(0, 0, 2)

p ~ em {
    color : red;
}

特殊情况

没有特指度的继承样式

继承样式不考虑特指度,由下面两个例子能说明:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>继承样式不考虑特指度</title>
        <style type="text/css">
            .yellow {
                color : yellow;
            }
        </style>
    </head>
    <body>
        <div class="yellow">
            <p>p标签</p>
        </div>
    </body>
</html>

上述例子中p元素的color属性值为red(来自用户样式表),继承自div元素的color属性值yellow被覆盖。

(\(\color{#FF3030}{注:此浏览器的用户样式表被我修改,没有修改过的p元素的color属性的值应该是black。}\))

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>继承样式不考虑特指度</title>
        <style type="text/css">
            .yellow {
                color : yellow;
            }
            p {
                color : green;
            }
        </style>
    </head>
    <body>
        <div class="yellow">
            <p>p标签</p>
        </div>
    </body>
</html>

上述例子中p元素的color属性值为green(来自元素选择器),继承自div元素的color属性值yellow被覆盖。

超脱特指度的 !important

!important是超脱特指度的存在

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>!important是超脱特指度的存在</title>
        <style type="text/css">
            #id {
                color : green;
            }

            p {
                color : brown;
            }
        </style>
    </head>
    <body>
        <p id="id">p标签</p>
    </body>
</html>

修改代码,给元素选择器中color属性加上!important后:

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>!important是超脱特指度的存在/title>
        <style type="text/css">
            #id {
                color : green;
            }

            p {
                color : brown !important;
            }
        </style>
    </head>
    <body>
        <p id="id">p标签</p>
    </body>
</html>

元素选择器中加了!important的声明覆盖了ID选择器中没加!important的声明。

特指度相当时 以 后声明的属性为准

当两个选择器的特指度相当时,特指度相当时 以 后声明的属性为准。

<!DOCTYPE html>
<html>
    <head>
        <meta name="charset" content="utf-8"/>
        <title>特指度相当时 以 后声明的属性为准</title>
        <style type="text/css">
            p {
                color : green;
            }
            p {
                color : brown;
            }
        </style>
    </head>
    <body>
        <p>p标签</p>
    </body>
</html>

后声明的属性覆盖了先声明的属性。

总结

单个选择器的特指度按照 !important > id选择符 > class选择符、属性选择符和伪类 > 元素选择符和伪元素的规律排序,如果遇到组合选择器,则按其逻辑将其拆分为单个选择器后相加再进行判断。如果选择器中的声明包含了!important,则这条属性会覆盖同属性所有不包含了!important的声明,只有在同属性的声明也包含!important,并且同属性的声明位于的选择器的特指度大于先前的选择器,亦或两个选择器的特指度相当,但同属性的声明位于的选择器位于先前的选择器之后时,才会覆盖先前的选择器的加了!important的属性。

如果上面的话很难理解,可以看这里的:
第一条:比较各自所在的选择器的特指度,特指度越大的优先级越高;
第二条:加了!important的声明的属性优先级最高,在都加了!important的情况下按第一条为准;
第三条:在特指度相等的情况下,后声明的优先级大于先声明的;
第四条:优先级高的样式覆盖优先级低的样式。

(0)

相关推荐

  • 一篇文章带你了解建设数字乡村问题有哪些?

    数字乡村是伴随网络化.信息化和数字化在农业农村经济社会发展中的应用,以及农民现代信息技能的提高而内生的农业农村现代化发展和转型进程,既是乡村振兴的战略方向,也是建设数字中国的重要内容.虽然数字乡村有着 ...

  • 一篇文章带你搞定牛吃草问题

    牛吃草问题,是小学数学一种重要的类型,又称为消长问题或牛顿问题,由17世纪英国科学家牛顿提出. 当年牛顿曾编过这样一道题目:牧场上有一片青草,每天都生长得一样快. 这片青草供给10头牛吃,可以吃22天 ...

  • 一篇文章带你搞定火车过桥问题

    火车过桥问题,在小学数学中是一种非常重要的行程问题. 难点在于,如果不太会画图的话,很容易找错路程之间的关系. 今天,就来给大家再总结一遍火车过桥中的一些基本情况,尤其是每种情况的图要分辨清楚. 孩子 ...

  • 一篇文章带你读懂湖田窑!资深藏家必看!

    湖田窑水晶莹玉润,白中泛青,色如湖蓝,极富情趣,刀法简捷明快,娴熟自然,结合造型.底足工艺特征判断,是开门的宋代湖田窑精品特征.湖田窑是汉族传统制瓷工艺中的珍品,位于今景德镇市东南湖田村,是中国宋.元 ...

  • 一篇文章带你了解强迫症!

    许多人都喜欢拿强迫症自居或者开玩笑,其实真实的强迫症一点都不好玩.本篇文章将带您了解强迫症到底是怎么一回事. 许多人认为,强迫症就是反复检查和洗手.其实不然.在临床调查中,50%左右的病人都有检查和清 ...

  • “吃素”到底好不好?一篇文章带你看穿素食的真相

    有人说, 人类进化了几十万年才爬上食物链的顶端, 可不是为了吃草. 然而,现在吃素的人越来越多了. 素食日渐风靡. 过去吃素可能是为了信仰,宗教,为了不杀生. 如今吃素是为了健康. 那么吃素有什么好处 ...

  • 为什么特发性震颤久治不愈?一篇文章带你深入了解它

    什么是特发性震颤?很多患者不知道该如何判断特发性震颤是属于哪种疾病,甚至认为特发性震颤是单纯的神经疾病与躯体疾病,对特发性震颤没有正确的认识,从而导致没有达到对症治疗,病情不但没有缓解反而越来越严重. ...

  • 想了解道家?一篇文章带你全面解锁

    通过对<庄子·外篇>的考察,除典型的庄子自由哲学形态外,还包含黄老道家哲学形态.神仙修炼道家形态.技艺武功修炼道家形态等.本文3755字,阅读大致需要10-15分钟.‍‍‍ 庄子分为< ...

  • 特发性震颤怎么办,一篇文章带你了解

    特发性震颤早期症状,一般会出现步态异常,患者通常都是以上肢开始,主要影响上肢双侧上肢对称起病也可单侧上肢起病.一旦上肢影响后常向上发展至头.面舌.下颚部,累及躯干和双侧下肢者少见,仅在病程的晚期出现, ...