CSS Handbook · 基础与层叠

第一章 / 1.2 层叠与继承

第一章 · 1.2 节

层叠与继承


CSS 的全称"层叠样式表"里,"层叠"(Cascade)二字点明了它的核心运作机制:当多条规则同时作用于同一个元素时,浏览器需要一套算法来决定最终生效的是哪一条。理解层叠与继承,是排查"样式怎么不生效"的根本功夫。

层叠的三个维度

当同一元素的同一属性被多条规则命中时,浏览器依次按以下维度决出胜负:

  1. 来源与重要性——用户代理默认样式 < 用户样式 < 作者样式 < 作者 !important < 用户 !important,作者样式的优先级通常最需要关注。
  2. 选择器优先级(specificity)——来源相同时,比较选择器的"精确程度",详见下一节的选择器优先级规则。
  3. 源码顺序——来源与优先级都相同时,后声明的规则覆盖先声明的规则。
提示这也是为什么把「重置样式」放在最前面、把「覆盖样式」放在最后面是常见约定——源码顺序是层叠算法里最后、也最容易被忽视的一环。

优先级速览

选择器优先级可以粗略拆成四级,通常记作 (a, b, c, d)

级别包含示例
a行内样式style="..."
bID 选择器#header
c类 / 属性 / 伪类选择器.btn、[type], :hover
d标签 / 伪元素选择器div、::before

逐级比较,高位相同才比较低位;!important 和继承不参与这套计数,通配符选择器 * 的优先级为 0。更完整的组合选择器优先级示例见 2.2 组合选择器与优先级

!important

.btn {
  color: red !important;
}
警惕!important 会跳过正常的优先级比较,直接把该声明提到"几乎最高"的位置。滥用它会让样式变得难以覆盖、难以维护,团队协作中通常仅允许在极少数场景(如覆盖第三方库样式)使用。

继承

部分 CSS 属性会自动从父元素"继承"到子元素,无需重复声明——这通常是与文字排印相关的属性,因为它们符合直觉:给 <body> 设置字体,页面里所有文字自然都用这个字体。

类型示例属性
默认继承color、font-family、font-size、line-height、letter-spacing、text-align、visibility
默认不继承margin、padding、border、width、height、background、display、position

不继承的多为盒模型与布局相关属性——如果 margin 也能继承,几乎所有布局都会失控。

inherit / initial / unset / revert

四个通用关键字可以显式控制任意属性的取值来源:

关键字作用
inherit强制从父元素继承,即使该属性默认不继承
initial重置为 CSS 规范定义的初始值(与继承无关)
unset该属性默认可继承则等同 inherit,否则等同 initial
revert回退到浏览器默认样式表(或用户样式表)中的值,忽略作者样式
.reset-all {
  all: unset; /* all 可以一次性应用到几乎所有属性 */
}

常见误区

  • 把"后写的规则一定生效"当作唯一规则——源码顺序只在优先级相同时才起决定作用,一个更精确的选择器即使写在前面也会赢。
  • 误以为 borderbackground 会继承——它们默认不继承,子元素需要单独设置或用 inherit
  • !important "快速修复"层叠问题——这只是把问题往后拖,后续任何想覆盖它的样式都得跟着加 !important,形成优先级军备竞赛。