从头开始复习css之选择器(下)
本来想随便写写就完事儿了,结果前两篇文章就已经写到了1点多才写完,昨晚睡觉的时候还在想 我写的东西是不是将我写的东西给描述清楚了?还有没有遗漏的?所以一大早就起来改了一个小时才改完。现在开始写下一篇文章吧。
前面两篇文章也差不多完完全全的将选择器的内容都阐述了一遍,但是在日常开发中我们可能会遇到这样一种困扰:当两种选择器有样式冲突的时候 我们应该优先选择哪种呢?
如果突然之间有人问我这个问题,我可能是懵懵懂懂的感觉懂,但是又说不出所以然来,最后可能憋出来一些最常规的回答:内联样式优先级>ID选择器优先级>类选择器的优先级>元素选择器的优先级等等。
但是这些个回答到底是对不对呢?我们来看下面一段代码:
// html
<p style="background-color: black"></p>
// css
p{
width: 100px;
height: 100px;
margin: 100px auto;
}
p {
background-color: red !important;
}
效果
很明显背景颜色并灭有被渲染成黑色,而是被渲染成了红色。这里我们就可以知道,其实内联的优先级并不一定会大于id选择器。
其实就我们开发的css规则而言,一般css规则由选择器和声明块组成。如下图所示
css结构组成
由上面的效果可以知道:对于元素p的背景颜色,我定义了元素选择器和内联两种方式来定义background属性,但是从上面的效果我们发现,最终却是元素选择器的内容起作用了。由此可见关于元素选择器内部必定有会有优先级顺序,下面我们来讲讲这个优先级(css权威指南上面称之为特殊性)的问题。
我们将选择器通过特殊值表述来分为4个部分,用0,0,0,0来表示。
- 对于选择器中给定的ID属性值,加0,1,0,0。
- 对于选择器中给定的各个类属性、属性选择、伪类,加0,0,1,0
- 对于选择器中给定的各个元素和伪元素,加0,0,0,1
- 通配符选择器(*)的特殊性(优先级)为0,0,0,0
- 内联声明的特殊性都是1,0,0,0
- 结合符和继承是没有特殊性
- css规则中位置靠后的声明会覆盖前面的声明
- 重要声明(!important)
另外值得注意的几点是:
1、 在都没有不考虑重要声明的情况下,如果多个规则与同一个元素的相匹配,并且有些声明相冲突的情况下,优先级越高(特殊性性越强)的越占优势。
2、 重要声明的优先级是最高的,如果两个规则都同样存在重要声明的时候,就考虑下一条。
2、 多个特殊性相同的选择器累加是不会进位的,也就是在不考虑都含有和不含有重要声明的前提下,元素选择器的优先级肯定会大于多个类选择器的优先级的。(有个有趣的点是:在某些浏览器中,255个类选择器累加的优先级是会超过id选择器的优先级,但是实际开发中不可能有人无聊到写255个类选择器把)
4、 特殊性为0的优先级要大于没有特殊性的元素,意思就是通配符选择器的优先级会大于继承/结合符的优先级。
5、 如果存在两条这样的规则,如果两个规则的优先级,重要声明都相同的情况下,靠后定义的规则会覆盖前面的规则。
就上面总结的内容来说呢?在html中,如果要确定一个元素应用css中的哪些规则的时候,浏览器要考虑的点有:父元素的继承、声明的优先级、还要考虑到本身的来源等等因素,综合这所有的因素,然后再进行特殊性优先级考量、规则排序,最终才能确认元素的最终效果。
最后我们就上面的总结,来简单的看下面几段代码:
- 首先我们来测试同级特殊性累加和上级特殊性的优先级问题
// html
<p id="test1" class="test1 test2 test3">我是用来测试第一条的</p>
// css
.test1[class].test2.test3{
background-color: red;
}
#test1 {
background-color: white;
}
效果如下:
效果如下
这里我们发现一个问题:无论如何累加,0,0,1,0的优先级都会小于0,1,0,0.
- 再看测试通配符和继承优先级
// html
<div>
<p>我是用来测试通配符和继承优先级的</p>
</div>
// css
* {
color: red;
}
div{
color: yellow;
}
效果如下:
效果
如果没有通配符选择器的情况下,p肯定会被继承父元素的color的属性,此时用了通配符选择器之后 我们发现其颜色被渲染成了红色,这充分说明了通配符的优秀级(0)会大于没有特殊性属性的优先级。
- 然后来看看上一篇文章我们提到的爱恨原则,通过这个我们规则的顺序覆盖问题:
// html
<a>链接一</a>
// css
a:hover{
color: green;
}
a:active {
color: yellow
}
a:link {
color: black;
}
a:visited {
color: red;
}
效果如下:
效果.gif
由上面的现象我们可以清楚的发现,动态链接的样式被“吃掉了”,而吃掉的原因呢?就是因为后面的link和visited将前面的超链接属性给覆盖掉了。
- 最后我们来整一个我自己都不怎么清楚的例子(哈哈)
// html
<div id="test">
我是用来测试属性选择器和id选择器的优先级的
</div>
// css
#test {
color: red;
}
div[id="test"]{
color: yellow;
}
效果如下:
效果
很多朋友可能在看的时候会把后者的属性选择器当作是id+属性选择器的累加,从而计算成0,1,1,0,从而认为他的特殊性会大于id选择器,然后后者其实还是一个属性选择器,特殊性依然是:0,0,1,0。
说在最后
一个清明,我和我妈基本都在各自领域里面不断的学习。看到我妈都快50岁的人了, 依然对知识有这么高的追热情,搞的自己有点不好意思了,还是得多学一点 不然都没办法实现今年年初许下的诺言了。