样式计算
解析HTML会得到DOM树和CSSOM树, 样式计算结束后会得到一棵具有样式的DOM树.
计算声明值
在这个过程, 会将我们代码里red之类的东西转为rgb(255, 0, 0)这种绝对值.
然后找到没有冲突的属性, 确定对应的值.
层叠
当样式冲突时, 浏览器会依次比较来源, 优先级, 源码顺序.
来源
- Transition(过渡中的样式): 正在执行CSS过渡的属性
- !important浏览器默认样式
- !important用户自定义样式
- !important作者样式
- Animation: 正在执行动画的css属性
- 普通作者样式: 我们平常写的代码
- 浏览器默认样式
优先级依次从高到低.
优先级
通过一个四元组来判断, 依次比较:
- 是否是内联, 是就是1, 不是就是0
- id选择器的数量
- 属性, 类, 伪类的数量
- 元素, 伪元素的数量
比如
css
#a .a .b h1 {
font-size: larger;
}
h1 {
font-size: large;
}那么四元组计算出来就是第一个里面的是0, 1, 2, 1, 第二个的是0, 0, 0, 1
依次比较, 会发现id选择器的数量是第一个大, 那么对于#a .a .b h1, font-size是larger.
源码顺序
源码中, 靠后的覆盖靠前的.
css
h1 {
font-size: larger;
}
h1 {
font-size: large;
}下面的靠后, 所以h1的font-size是large.
btw, 一般的编辑器比如vscode有类似功能, 可以直接查看计算结果. 把鼠标放上去就会显示了. 不过一般会忽略掉第一个值, 比较放在选择器上肯定不是内联样式了.
通过层叠, 我们可以为冲突的属性确定唯一值.
继承
经过前面两个步骤, 如果还有一些属性没确定, 如果可以继承, 那么就会继承.
什么时候可以继承
- 这个属性没有值
- 这个属性可以继承
一般文字相关的都可以继承, 比如font-size
使用初始值
经过前面三个步骤, 可能还是有些属性没有值. 那就会用初始值了.
一些特殊值
inherit
在层叠阶段进行"继承", 但是这种继承不在乎属性值可不可以继承, 是简单粗暴地将父元素的属性值复制过来.
initial
使用初始值
unset
让这个属性值可以参与继承和使用初始值, 不使用浏览器默认样式.
revert
让这个属性值使用浏览器默认样式, 或者空.