CSS 属性计算过程:从声明到最终值
确定声明值、层叠冲突、继承与默认值——搞懂 Computed 面板里那一长串属性是怎么来的。
CSS 属性计算过程:从声明到最终值
写 CSS 时往往只写几行:
p {
color: red;
}
但打开开发者工具 → 元素 → 计算样式 → 勾选「全部显示」,会发现每个元素都有 成百个属性。它们从哪来?为什么有的没写却有值,有的写了却不是你以为的结果?
属性值的计算大致分 四步:确定声明值 → 层叠冲突 → 使用继承 → 使用默认值。算完后的结果会进入渲染流水线的 样式计算 阶段,再与 包含块 一起在布局里定稿几何尺寸。
每个元素都有一套完整样式
<body>
<h1>这是一个 h1 标题</h1>
</body>
没给 h1 写任何样式,它仍有默认字号、颜色等——因为 任意 HTML 元素都对应一整套 CSS 属性;没写的,多数走继承或 用户代理样式表(浏览器默认样式)。
在计算样式里勾选全部显示即可验证:
注意:没写 不等于 一定用默认值——中间还有 继承 和 层叠,所以必须理解计算流程。
第一步:确定声明值
声明值 就是样式表里写明的规则,包括:
- 作者样式表(你写的 CSS)
- 用户代理样式表(浏览器内置,如
h1的display、margin)
若声明之间无冲突,直接采用对应声明。
第二步:层叠冲突
多条规则声明同一属性时,进入 层叠(Cascade) 解决,细分为:
- 比较 源的重要性
- 比较 优先级(特异性)
- 比较 次序
比较源的重要性
样式来源(重要性从高到低):
- 页面作者样式
- 用户样式(用户自定义)
- 用户代理样式
作者与用户代理同时声明 display 时,作者胜出:
p {
color: red;
display: inline-block;
}
详见 MDN:Cascade
比较优先级
同一源内冲突,比 选择器权重:
<div class="test">
<h1>test</h1>
</div>
.test h1 {
font-size: 50px;
}
h1 {
font-size: 20px;
}
.test h1 权重更高 → 50px:
落败规则在 Styles 面板中会被划掉。
比较次序
同源、同权重时,后面的规则覆盖前面的:
h1 {
font-size: 50px;
}
h1 {
font-size: 20px;
}
最终 20px:
第三步:使用继承
没有声明的属性,若该属性 可继承,则从 最近的祖先 取值:
<div>
<p>Lorem ipsum dolor sit amet.</p>
</div>
div {
color: red;
}
p 的 color 来自 div:
强调 最近祖先:
<div class="test">
<div>
<p>Lorem ipsum dolor sit amet.</p>
</div>
</div>
div {
color: red;
}
.test {
color: blue;
}
内层 div 更近 → p 继承蓝色(这里不比权重,因为根本没选中 p):
哪些属性可继承?查 MDN 各属性页,例如 text-align:
第四步:使用默认值
仍无法确定的,用 initial / 用户代理默认值:
元素要在浏览器里渲染,必须具备完整属性集;大量属性既未声明、也无法继承,就靠这一步补齐。
面试题:a 和 p 各是什么颜色?
<div>
<a href="">test</a>
<p>test</p>
</div>
div {
color: red;
}
a:用户代理样式表里已为链接声明了color,有声明值,不继承div的红色。p:作者与 UA 都未给p声明color,而color可继承 → 从div继承红色。
小结
- 计算样式四步:声明 → 层叠 → 继承 → 默认。
- 层叠内部:源 > 权重 > 次序。
- 继承看 最近祖先,与选择器权重无关。
- 算出的 Computed Style 是渲染流水线「样式计算」的输入;百分比尺寸还要等 布局与包含块。