跳到主要内容

CSS 继承与层叠

面试速答(30 秒版 TL;DR)

  • **继承(Inheritance)**解决的是“当前元素自己没写值时怎么办”;**层叠(Cascade)**解决的是“多个候选值同时存在时到底听谁的”。
  • 一般规律是:文字排版相关属性更容易继承,如 colorfont-*line-heighttext-align盒模型和布局相关属性通常不继承,如 marginpaddingborderwidthdisplayposition
  • 层叠的高频答法记一句:来源与重要性 -> 层叠层 @layer -> 权重(Specificity) -> 书写顺序
  • 如果想手动控制结果,可以用:inheritinitialunsetrevert

心智模型

浏览器在算样式时,不是“整个元素一次性算完”,而是对每个元素的每个属性单独求值。

color 为例,浏览器大致会这样判断:

  1. 当前元素自己有没有命中的 color 声明?
  2. 如果有多个候选值,就进入层叠比较。
  3. 如果一个都没有,再看 color 是否可继承。
  4. 可继承就拿父元素的最终值,不可继承就回到初始值。

所以你可以把它记成两句话:

  • 没有值时,看继承。
  • 有多个值时,看层叠。

一、继承到底是什么

继承不是“子元素复制父元素全部样式”,而是:

当某个属性默认支持继承,且当前元素没有拿到更直接的值时,使用父元素的最终计算值。

例如:

<div class="card">
<h2>标题</h2>
<p>正文</p>
</div>
.card {
color: #334155;
font-size: 16px;
}

这时 h2p 会继承到 colorfont-size。但如果你给 p 单独写了 color,那它就不再使用继承值。

常见可继承属性

类别常见属性
文字颜色color
字体font-familyfont-sizefont-weightfont-style
文本排版line-heighttext-alignletter-spacingword-spacing
列表/光标/可见性list-stylecursorvisibility
自定义属性--brand-color--space-md

常见不可继承属性

类别常见属性
盒模型marginpaddingborderbox-sizing
尺寸widthheightmin-width
布局displaypositionfloatflexgrid-*
背景与变换backgroundtransformoverflow

二、层叠到底比什么

当同一个元素的同一个属性被多条声明命中时,浏览器要从这些候选值里选一个赢家。

面试里最实用的表达顺序是:

  1. 来源与重要性:浏览器默认样式、用户样式、作者样式,以及是否带 !important
  2. 层叠层@layer
  3. 权重:Specificity
  4. 书写顺序:后写覆盖先写

例如:

.title {
color: #64748b;
}

.card .title {
color: #0f172a;
}

同一个 title 命中了两条 color,因为第二条权重更高,所以最终颜色是 #0f172a

高频误区

HTML 里 class="a b" 的先后顺序,不决定谁赢。真正决定结果的是 CSS 规则的层叠比较,不是类名在属性里的排列顺序。


三、4 个关键字怎么答

1)inherit

强制当前属性继承父元素的最终值。

.child {
color: inherit;
}

2)initial

把属性恢复到规范定义的初始值,不是恢复到父元素值。

.box {
position: initial; /* 回到 static */
}

3)unset

  • 对可继承属性,效果像 inherit
  • 对不可继承属性,效果像 initial

4)revert

回退到更早一层来源中的值,常用于“撤销当前作者样式”,但面试里知道语义即可,不必把它讲成高频日常写法。


四、典型题 & 标准答法

Q1:为什么子元素没写颜色,还是和父元素一样?

答法:

  • 因为 color 是可继承属性。
  • 当前子元素自己没有更直接的 color 声明,所以浏览器取父元素的最终值。

Q2:为什么我明明写了样式,但没生效?

答法:

  • 先确认规则有没有命中目标元素。
  • 命中了再看是不是在层叠里输了:可能输在 !important@layer、权重或者书写顺序。
  • 如果当前属性本身没有被当前规则赢下来,页面上显示的可能是继承值或别的规则的结果。

Q3:内联样式是不是一定最大?

答法:

  • 不是绝对这么说。
  • 内联样式在普通作者样式里权重很高,但外部样式里的 !important 可以覆盖内联的普通声明。
  • 所以面试更准确的说法是:先分重要性赛道,再比权重。

常见追问

1)浏览器默认样式算继承吗?

不算。那是浏览器的默认样式表(User Agent Stylesheet),来源和继承不是一回事。

2)子元素继承的是父元素哪一个值?

继承的是父元素层叠完成后的最终计算结果,不是父元素某一条原始声明。

3)CSS 变量为什么常说“天然适合主题”?

因为自定义属性默认可继承,父级定义一次,后代就能直接消费或局部覆盖。


易错点/坑

  • 把“继承”和“后写覆盖前写”混为一谈,这其实是两套机制。
  • 以为所有属性都能继承,尤其容易误判 marginpaddingborderdisplay
  • initial 误认为“回到父元素的值”;实际上它是回到属性初始值。
  • 以为只要选择器命中了就一定生效,忽略了层叠里的输赢关系。

速记要点(可背诵)

  • 继承处理“没有值怎么办”,层叠处理“多个值听谁的”。
  • 文字排版多继承,盒模型布局多不继承。
  • 层叠顺序常用答法:来源与重要性 -> @layer -> 权重 -> 顺序。