层叠
CSS中通过层叠的机制来处理多个规则同时作用于一个元素的情况。这是一个非常重要的概念,通过CSS(层叠样式表)的名字就可以得知。
层叠的机制: 为不同的规则赋予不同的重要性。
这就像是生活中,领导给你分配任务,领导说:“小猪,你去给我倒杯水。” 接着又说:“小猪,你给我拿点吃的。” 你还没走呢,领导又说:“小猪,来给我按按摩。” 小猪没有修过分身术,只能一件一件地做,从哪一个开始呢? 那就看哪件事情最重要啦,不然要被领导炒鱿鱼了,肯定给领导按按摩最重要啦是不是。
CSS的层叠规则
- 找到匹配特定元素的所有规则
- 按照显示权重排序应用到特定元素上的所有规则声明。以!important标记的规则比没有!important标记的规则的权重高。
- 按照来源排序应用到特定元素上的所有声明。声明有三个来源:开发者、用户和用户代理(浏览器)。正常情况下,开发者编写的样式击败用户编写的样式;用户样式中用!important标记的样式比其他样式权重高,包括开发者样式中以!important标记的样式;开发者样式表和用户样式表中的规则声明都会覆盖用户代理的默认样式。
- 按照特殊性排序应用到特定元素上的所有声明。特殊性高的样式具有较高的权重。
- 按声明的前后位置排序应用到特定元素上的所有样式。样式表或文档中靠后的声明权重较高。导入的样式表中的声明放在当前样式表中所有声明的前面。(因为,@import url(...)的位置就在style标签内的所有规则之前。)
规则的权重
最重要的规则是作者样式表,即开发者所写的样式。再次是用户样式表,用户可以通过浏览器的设置选项,为网页应用自己的样式。排在最后的是浏览器(或用户代码)的默认样式,但一般会被作者样式表所覆盖。为了给用户更高的优先权,CSS允许用户使用!important覆盖任何规则,包括作者使用!important的样式。
**毕竟,咱们作者只是下等搬砖的,用户才是上帝 : ) **
层叠机制的重要性级别从高到低为:
- 用户!important设置的样式
- 作者使用!important设置的样式
- 作者样式表
- 用户样式表
- 浏览器(或用户代码)默认样式表
在这些级别的基础上,规则再按照规则的特殊性或者说是重要性排序。
概括CSS样式匹配
首先找到匹配特定元素的所有样式声明,先按照权重和来源进行排序,排序之后的样式如果存在冲突(即,多个规则的权重和来源相同),则根据各个规则的特殊性来选择应用的样式。若是多个规则的权重、来源以及特殊性均相同,则根据这些规则在样式表中的先后顺序来选择应用的样式。
特殊性(重要性)
为了量化规则的特殊性,每种标识符都对应着一个数值。那么,一条规则的特殊性就是其每个选择符的累加数值。
任何选择符的特殊性都对应着4个值:a , b , c , d
- 对于行内样式 a = 1
- b 为 ID选择符的个数
- c 为类选择符,伪类选择符 以及属性选择符的个数
- d 为元素选择符 , 伪元素选择符的数目
下面是一个例子
选择符 | 特殊性 |
---|---|
style = "" | 1,0,0,0 |
*#a #b {} | 0,2,0,0 |
*#a .b{} | 0,1,1,0 |
div#a{} | 0,1,0,1 |
*#a {} | 0,1,0,0 |
p.a .b{} | 0,0,2,1 |
p.a {} | 0,0,1,1 |
div p {} | 0,0,0,2 |
p{} | 0,0,0,1 |
虽然当选择符的数量不超过10个时,也可以用十进制表示特殊性,但是小猪哥还是不建议使用十进制,因为以上的方式非常容易看出来不同规则的特殊性大小。(1,0,0,0 肯定大于 0,2,2,2)
比较特殊性的值的大小方法:a,b,c,d 四个值,对于最前面的值大的,后面就不需要比较了,比如 1,0,0,0 和0,2,2,2 因为第一位a的值中1,0,0,0比0,2,2,2大,所以第一个的特殊性大(1,0,0,0)。从第一位a开始比较,若值相同,则继续找下一位b的值进行比较,以此类推。
总的来说,如果样式是写在元素的style属性里的,那么这些样式的特殊性最高。其次,是通过ID选择符应用的样式的特殊性高于不使用ID选择符的。类选择符同理。如果特殊性相等,则由应用后定义的规则。
(内联式样式 > ID选择符样式 > 类选择符样式 > 外部文件中设置的样式)
好了,我们来练习一下!
<div id = "Div">
<h1>hello</h1>
<div id = "childDiv">aovbais</div>
<div>auioabsiahsfo</div>
<div>lohvwoie</div>
</div>
//CSS
#childDiv
{
background:black;
color:white;
}
#Div #childDiv
{
background:orange;
color:blue;
}
最终的id 为 childDiv 的div 样式会是怎样的呢?
我们通过上面的层叠样式表来确定特殊性的值的大小。
- 选择器#childDiv 的特殊性值为 0,1,0,0
- 选择器 #Div #childDiv 的特殊性值为: 0,2,0,0 这是因为该规则使用了两个ID选择符
继承
继承,很好理解,就像我们的社会中的一样,元素从父元素或者是祖元素得到和它们相同的属性。
一些属性,会被应用他们的元素的后代继承。比如,我们设置body的颜色为红色,那么body所有后代的颜色都会继承这个颜色。
body
{
color:orange;
}
<ul id = "nav">
<li><a href="#">Home</a></li>
<li>Servies</li>
<ul>
<li>Design</li>
<li>Development</li>
</ul>
<li>Contact us</li>
</ul>
结果是字体全为橙色。但并不是所有的情况下都是这样的,假如我们给body元素设置一个字号,但是body内部的标题的字体不会发生变化。
body{
font-size:2em;
}
<h1>Hello,welcome to my blog!</h1>
<ul id = "nav">
<li><a href="#">Home</a></li>
<li>Servies</li>
<ul>
<li>Design</li>
<li>Development</li>
</ul>
<li>Contact us</li>
</ul>
结果是body样式中的字体大小font-size是无用的。
这是因为,有些标签的默认样式是由浏览器默认样式表设置的。这还是前面说的特殊性的问题。
继承来的属性值没有任何特殊性,甚至连0都不是,因此即使是特殊性为0的通用选择符设置的样式也会覆盖元素继承来的样式。
*
{
color:orange;
}
ul
{
color:purple;
}
<h1>Hello,welcome to my blog!</h1>
<ul id = "nav">
<li><a href="#">Home</a></li>
<li>Servies</li>
<ul>
<li>Design</li>
<li>Development</li>
</ul>
<li>Contact us</li>
</ul>
当在网页中打开时,我们会发现,页面中所有的字体的颜色都是橙色。但我们的CSS中,把UL中的所有字体都设置成了紫色啊!
我们的文字是在 li 标签里面的,li标签是ul标签的子节点,因此li标签会继承紫色,但是我们又通过通用选择符来给所有的元素设置文本颜色为橙色。这个时候就要看样式的特殊性了,由于继承来的样式的特殊性连0都算不上,而通用选择符的特殊性为0,因此页面中的字体颜色显示为橙色。