CSS 与布局 / How does CSS work · 样式从哪来 / 四层默认样式:一个值的来路 待审核 1 / 6
overview · 4 levels

四层默认样式:一个值的来路

一个属性最终生效的值,是浏览器按优先级从下往上叠出来的。本页把它拆成四层来讲——这是沿用 Elad Shechter 那篇文章的教学分层,规范里的 origin 只有 UA、user、author 三个,Normalize 与 Reset 都属 author origin 的普通样式表,彼此靠层序或 @layer 决胜;而 initial value 根本不在层叠里,它属于层叠没产出值时的 defaulting 兜底。在写下任何自定义 CSS 之前,已经有这几层在排队——

  1. Level 1 · Initial value——每个属性在规范里都有一个初始值,不针对任何标签。
  2. Level 2 · User-Agent stylesheet——浏览器内置样式表,针对具体标签覆盖初始值。
  3. Level 3 · Normalize——(可选)抹平不同浏览器之间 UA 样式的差异。
  4. Level 4 · Reset——(可选)项目开头主动清掉不想要的默认值。

后两层要自行引入才存在,本页先只看前两层。下面用 getComputedStyle 读出各属性的解析结果并作对照——注意它返回的是 resolved value:多数属性等于 computed value,但 width / height / margin-* / padding-* 这一批返回的是已折算成像素的 used value

图 1 · 逐个属性对照 initial value 与 UA 值,读数用 getComputedStyle 取得(多数属性等于 computed value,尺寸类返回 used value)。

关键直觉: display 的 initial value 实为 inline——<div> 之所以是块级,不是因为「div 天生是块」,而是因为 UA stylesheet 里写了 div { display: block } 把初始值盖掉了。把属性切到 display 即可验证。

1 · 分层的意义

分层让「覆盖」变得有秩序:author 样式优先级高于 user、user 高于 UA。规范初始值不参与这个排序——它是层叠没能给出值时的兜底(可继承属性先取父值,否则取 initial value)。Normalize 和 Reset 不是浏览器给的,而是为了跨浏览器一致清空默认而主动插进 Level 3/4 的那一层。规范默认值与继承User-Agent StylesheetNormalize vs Reset三页分别展开这几层。