CSS选择器的优先级详解

一.特指度(specificity)

咱们可使用不一样的方式去选择元素,而后使用你指定的样式。那同一个元素有可能会被多个规则选择,并且每一个规则的选择符不尽相同。例以下面这样:css

p{
    color: red;
}
body p{
    color:green;
}

<p>
    hello world!
</p>
复制代码

上面的一对规则只能由一个胜出,由于文字的元素不可能即显示红色,又显示绿色。那么咱们如何知道哪一个规则的优先级更高呢? 答案是每一个选择器的特指度不一样,浏览器会计算每一个规则中的特指度,而后应用到规则中的每一个声明。若是属性声明之间有冲突,那就应用特指度更高的那个样式。(能够将特指度理解为优先级)html

选择器的特指度由选择器自己的组成部分决定。一个特指度由四部分组成,例如0,0,0,0。 选择器的特指度规则以下:浏览器

  • 行内样式的特指度为1,0,0,0
  • 每个ID选择器加0,1,0,0
  • 每个类选择器、属性选择器、伪类加0,0,1,0
  • 每个元素和伪元素加0,0,0,1
  • 通用选择器不增长特指度,也即通用选择器的特指度为0,0,0,0
  • 继承的值没有特指度,即连0,0,0,0都没有
  • 若给一个元素的属性值增长了!important声明,则该声明的样式优先级最高

注意 :not()否认伪类的特指度在计算中不会被看做是伪类,可是在:not()内部声明的选择器是会影响特指度的,具体要看否认伪类里面的选择器是什么类型了。 bash

例如:markdown

p:not(.title) span{color:red;} 特指度为0,0,1,2
p:not(h1) span{color:red;} 特指度为0,0,0,3
复制代码

再举下面几个例子,下面计算一下某一个选中元素的特指度ide

h1{color:red;}           特指度为0,0,0,1   
h1.title{color:green;}   特指度为0,0,1,1 
*.title{color:yellow;}   特指度为0,0,1,0 
#side{color:silver;} 特指度为0,1,0,0 
body #side{color:skyblue;} 特指度为0,1,0,1 
h1 span{color:red;}      特指度为0,0,0,2 
p.bright span.title{color:blue;}  特指度为0,0,2,2 
*[href]{color:red;}      特指度为0,0,1,0 
p::first-letter{color:red;} 特指度为0,0,0,2 
p:first-child{color:green}  特指度为0,0,1,1 
复制代码

特指度计算出来了,那么哪一个特指度更大呢?(也即谁的优先级较高) 特指度从左向右进行比较。特指度为1,0,0,0比全部以0开头的特指度大,无论后面的数有多大。一样0,1,0,0比全部0,0,x,x要大,无论x取什么值,依此类推。一样0,1,1,0比0,1,0,0要大,若是两个特指度的某一个位置上的数相同就比较后面一位数字,谁的数字大,那么大的那个特指度就大,也即优先级更高。ui

特指度计算出来了,其值将赋予关联的每一个声明。 spa

对上述那句话举下面一个例子说明:
span{
    color: red;
    background-color: green;
}
span.title{
    color: violet;
}
<span class="title">are you ok?</span>
1.能够计算出span{color: red;background-color: green;}的特指度为0,0,0,1;这个特指度将赋予所关联的每一个声明,也就是说color:red和
background-color:green这两个属性值的特指度都为0,0,0,1
2.而span.title{color:violet;}能够计算出特指度为0,0,1,1,也即color:violet的特指度为0,0,1,1;这个颜色的优先级比前者高。故span元素的文本将显示violet颜色。可是背景色还
是显示为green颜色。由于后者没有声明背景色,那就仍是使用以前声明的背景颜色。
复制代码
下面举几个例子来讲明
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>css选择器优先级</title>
    <style>
        h1{
            color: red;
        }
        body h1{
            color: green;
        }
        h2{
            color: red;
        }
        h2.title{
            color: green;
        }
        p{
            font-size: 16px;
            background-color: yellow;
        }
        p.news{
            font-size: 24px;
        }
    </style>
</head>
<body>
  <!--1.  h1{color:red}的特指度为0,0,0,1;
  body h1{color:green}的特指度为0,0,0,2;故后者的特指度更高h1元素中的文本颜色将会
  应用green颜色-->
  <h1>china</h1>
  
  <!--2. 能够计算h2{color: red;}的特指度为0,0,0,1; 
  h2.title{color: green;}的特指度为0,0,1,1 后者胜出-->
  <h2 class="title">hello</h2>
  <!--3. p{font-size: 16px;background-color: yellow;} 这个元素所包含的全部属性值的特指度都为0,0,0,1
    p.news{font-size: 24px;}能够知道font-size属性的特指度为0,0,1,1。
    故font-size的大小将应用后面那个样式为24px,背景色仍是为黄色-->
  <p class="news">
        关于华为鸿蒙系统,另据国外媒体Huawei Central报道,有知情人士透露,华为的自
  </p>
</body>
</html>
复制代码

在任何状况下,浏览器都会肯定哪些规则与元素匹配,而后找出全部相关联的声明,计算每一个属性的特指度,判断哪些规则胜出,再把胜出的规则应用到元素上,获得装饰后的结果。code

通用选择器的特指度orm

通用选择器不增长特指度。即它的特指度为0,0,0,0。并非说没有特指度,继承才没有特指度(参见后面)。例如对于下列规则p元素的文本颜色将为red:

p{color:red;}  特指度为0,0,0,1
*{color:green;} 特指度为0,0,0,0
复制代码

ID选择器和属性选择器的特指度

ID选择器和属性为id的选择器的特指度是不一样的,不要混淆。例如对于下列规则id为title的元素的文本颜色将为green:

#title{color:green;} 特指度为0,1,0,0
[id="title"]{color:red;} 特指度为0,0,1,0
复制代码

行内样式的特指度

行内样式的特指度比其余声明都要高(除了!important)。例如对于下列规则的p元素的文本颜色将为violet:

p{color:red;}
<p style="color: violet">你好</p>
复制代码

!important

有时候某一个声明很重要,超过其它声明,你可使用!important。这种声明须要在声明末尾的分号以前插入!important,例以下面这样:

p{color: red !important;font-size:20px;}
复制代码

带有!important的声明对特指度没有影响。可是会与不重要的声明分开处理。全部带!important的声明放在一块儿处理,不带!important的声明会放在一块儿处理,其中的冲突使用特指度解决。

二.继承

继承是指某些样式不只应用到所指定的元素,还会应用到元素的后代身上。例如给ul列表元素设置color:red;样式那么其子元素li的文本也会变成红色。

ul{color:red;}

<ul>
    <li>hello</li>
    <li>china</li>
</ul>
复制代码

使用谷歌浏览器能够看到li的样式继承自它的父元素ul

也有不少属性是不继承的例如border、margin、padding等。

继承的值没有特指度,连零都没有(也即特指度为0,0,0,0的元素)。这一点须要特别注意。

看下面例子:

* {color:red;}
p.title{color:green;}

<p class="title">
    Welcome to china
    <span>haha</span>
</p>
复制代码

能够看到Welcome to china变成了绿色,原本span也会变成绿色,由于span元素会继承父元素的值,可是如今确实红色。缘由是上面通配选择器的特指度为0,0,0,0,而继承的特指度没有,故通配选择器的优先级更高,故span元素里面的内容也显示成红色了。

三.层叠

若是两个特指度相等的规则应用到同一个元素上面,那么浏览器如何解决这个冲突呢?例如这样:

p{color:red;}
p{color:green;}
复制代码

CSS采用层叠机制将样式组合在一块儿,即结合继承和特指度的一些规则。CSS层叠规则以下:

  • 1.找到匹配特定元素的全部规则
  • 2.按照显示权重排序应用到特定元素上的全部声明。以!important标记的规则比没有这一标记的规则权重高。
  • 3.按照特指度排序应用到特定元素上的全部声明。特指度越高权重越高。
  • 4.按照声明的先后位置排序应用到特定元素上的全部声明。样式表或文档中靠后的声明权重较高。导入的样式表中的声明放在当前样式表中全部声明的前面。

下面开始举例说明:

按照权重排序

p{coloe:red !important;}
<p style="color: violet">你好</p>
复制代码

因为!important标记的规则权重较高,故p元素的文本内容显示红色。

按照特指度排序

p.title{coloe:red;}
p{color:green;}
<p class="title">你好</p>
复制代码

那么以上就是特指度越高,就应用高的那个声明的样式,故上述p元素的文本内容显示红色。

按照先后位置进行排序 若是两个规则的权重和特指度都同样,那么按照样式表中位置越靠后的规则完胜。

h1{color:red;}
h1{color:green;}
<h1>谁胜出</h1>
复制代码

上述h1元素将应用第二条规则,也即h1元素的color将取green。

四.总结

层叠规则要按照显示权重、特指度、以及先后位置顺序进行判断。先比较权重,权重越高的规则胜出(如应用了!important),再看特指度,特指度越高的胜出,最后在权重和特指度相同的状况下看先后位置顺序,靠后的胜出。记住这一条规则,就不会出错了。

相关文章
相关标签/搜索