最近在看《CSS权威指南》,学习到选择器相关知识的时候收获颇丰,于是在这里记录一下。
层叠原理
CSS(Cascading Style Sheets 层叠样式表),可以看出对于CSS来说层叠是一个非常关键的机制。那么CSS是怎么个层叠法呢?
层叠,就是样式在文档层次中逐层叠加的过程
这里就引出了文档层次这个概念,浏览器在解析(层叠)CSS的过程中,对不同来源的样式表有着不一样的解析顺序。下面是浏览器层叠CSS不同来源样式表的顺序
- 浏览器默认样式表
- 用户样式表
- 作者链接样式表
- 作者嵌入样式表
- 作者行内样式表
浏览器按照从上到下的顺序依次解析样式表,而最终呈现出来的样式就是在这一层层的层叠中确定下来。具体来说就是浏览器会按照上述顺序一次检查每个来源的样式,并在有定义的情况下(按照优先级)更新对每个标签属性值的设定。
举个🌰。对于这样一个html结构中的p元素
<div class="a">
<div class="b">
<p>jojo</p>
</div>
</div>
HTMLCopy
假设分别有来自浏览器的默认样式表、作者链接的样式表a.css
和作者嵌入的样式表<style>
对其产生影响
/* browser */
p {
margin: 1rem 0;
letter-spacing: .5rem;
}
/* a.css */
.a .b p {
margin: 0;
}
/* style */
p {
margin: 5rem 0;
letter-spacing: .2rem;
}
CSSCopy
首先浏览器会解析浏览器的默认样式表,得到
p {
margin: 1rem 0;
}
CSSCopy
其次,浏览器会解析我引入的a.css
,发现对于这个p
元素来说,有来自浏览器和a.css
的两组规则都对其生效了,需要更新样式,观察a.css
中对p
元素的选择器为.a .b p
,而浏览器自带的样式表的却只是p
,所以a.css
中的所有规则的优先级都会高于浏览器自带的样式表。需要合并的属性只有margin
属性,所以就会使用a.css
中的margin
属性更新。而letter-spacing
属性不用更新,保留就好
得到
p {
margin: 0;
letter-spacing: .5rem;
}
CSSCopy
最后,浏览器解析我在html文件中的style
标签中的
p {
margin: 5rem 0;
letter-spacing: .2rem;
}
CSSCopy
和上面一样,先对比优先级,发现对于margin
属性来说,来自a.css
的.a .b p
选择器的优先级明显要高,那么就保留a.css
中的margin
属性值。
但是对于letter-spacing
来说,来自浏览器的样式和它的优先级一样,这里就是按照层叠原理中的后来后有效的规则对letter-spacing
进行更新。
最后得到的就是
p {
margin: 0;
letter-spacing: .2rem;
}
CSSCopy
小结
其实说到这里,有小伙伴就会说:“哎,这不就是CSS文件的优先级吗?”
没错,如果把刚刚的浏览器解析不同来源的CSS文件的顺序从下到上看,也能发现,这恰恰就是我们编写CSS时所理解的优先级概念。但是,可能大家不知道优先级为什么是这么来的(也可能只有我不知道,学习的时候还是做到知其然知其所以然是最好的啦~
