CSS 属性值的计算过程

浏览器需要确定所有 HTML 节点的所有 CSS 属性值,才能进行样式计算和布局。CSS 属性值的计算过程就是:某个元素从所有 CSS 属性没有值,到所有 CSS 属性都有值的过程

第一步:确定声明值

选择器匹配到的样式规则没有冲突(属性只有一个属性值)时,直接使用属性值

其中样式规则包括:

  • 作者样式:开发者写的样式
  • 代理样式:浏览器默认样式

第二步:层叠冲突

如果选择器匹配到的样式规则有冲突(多个样式规则给同一属性定义了不同的属性值),则进行层叠比较,以确定最终选择哪个属性值

第一步:重要性

根据样式来源和是否添加 !important 决定重要性

重要性从高到低:

  1. 带有 !important 的作者样式
  2. 带有 !important 的代理样式
  3. 作者样式
  4. 代理样式

第二步:特殊性

根据是否内联样式和选择器权重来决定特殊性

内联id属性元素
是:1;否:0id 选择器的数量属性、类、伪类选择器的数量元素、伪元素选择器的数量

从左到右进行比较

注:通用选择器(*)、复合选择器(空格、>+~)、否定伪类(:not)在特殊性中无影响

第三步:源次序

源码中靠后的样式规则覆盖靠前的

注意:比较的是样式规则声明的代码先后次序;而不是先写哪个类名,后写哪个类名的顺序

第三步:继承

如果作者样式和代理样式都没有指定某个属性的值,且该属性可以继承,则使用继承的属性值(继承遵循就近原则)

如何确定一个属性是否可以继承?可以查看 MDN 文档。一般来说,和字体相关的属性可以继承

第四步:初始值

如果作者样式和代理样式都没有指定某个属性的值,且该属性不可以继承,则使用该属性的初始值(所有 CSS 属性都有初始值)

第五步:计算值

通过上面四步就确定了某个元素的所有 CSS 属性值。之后进行计算:将预设值变成绝对值,比如 red 会变成 rgb(255, 0, 0)、相对单位变成绝对单位,比如 em 会变成 px

四种特殊的通用属性值

  • revert:有代理样式则使用代理样式,否则可以继承使用继承值、不能继承使用初始值
  • inherit:获取其父元素(文档树中的父元素,即使父元素不是包含块)的计算值(即:强制继承
  • unset:可以继承使用继承值、不能继承则使用初始值
  • initial:使用初始值

四种属性值都可以应用于任何 CSS 属性,包括 CSS 简写 all