CSS 继承
继承是 CSS 里一个特别贴心的机制,理解了它,很多样式不用写。它的意思是,父元素的部分样式会自动传给子元素。给 body 设了字体,整页文字都跟着变,这就是继承。
哪些属性会继承
不是所有属性都继承,有没有继承能力,取决于属性的”天性”,大致按两类分。
可继承的,基本都是和文字外观有关的属性。颜色、字体族、字号、行高、字重、文字对齐、文字间距,这些写在父元素上,子元素自动获得。给 body 写一行 font-family 和 color,全站文字的统一风格就定了,不需要每个元素都写一遍。
body {
font-family: sans-serif;
color: #333;
}
不可继承的,基本都是和盒模型有关的属性。宽度、高度、外边距、内边距、边框、背景、定位、浮动,这些描述的是元素自己的尺寸和位置,每个元素都不一样,自然谈不上继承。border 不继承这件事常被误解,给父元素加了边框,子元素不会各自长一圈边框,就是因为在它身上没有继承。
| 类型 | 代表属性 | 是否继承 |
|---|---|---|
| 文本类 | color、font-family、font-size、line-height、text-align | 继承 |
| 盒模型类 | width、height、margin、padding、border、background | 不继承 |
继承带来两个坑
第一个坑,继承的值权重很低。上一篇文章说过,继承来的样式,优先级排在所有直接声明后面。给父元素设了红色,给子元素写一条黑色,子元素立刻变黑,没有任何纠结。
第二个坑,background 不继承,但看起来像继承了。父元素设了背景色,子元素默认背景是透明的,透过子元素能看到父的背景,视觉上像继承了。其实它没继承,子元素自己设背景色,立刻盖住。理解这点,做嵌套卡片时就不会疑惑。
用 inherit 强制继承
遇到不想写、又确实需要的继承,用 inherit 关键字手动要过来。它把父元素的对应计算值强制拿过来用。
a {
color: inherit;
}
链接默认是蓝色的,加上这行,链接颜色跟随父元素的文字颜色,这是导航栏和卡片链接最常见的处理方式。
还有两个亲戚关键字,initial 和 unset。initial 把属性恢复成规范里的初始值,比如 color: initial 变回黑色。unset 更聪明,这个属性默认会继承就用 inherit,默认不继承就用 initial。这几个关键字的完整规则,可以翻CSS 属性关键字那篇。
继承链
继承沿着 DOM 树一路向下传递,爷爷传给爸爸,爸爸传给儿子。中途任何一个节点显式设置,链就在这里断掉,以下所有后代用新值。
<div class="outer">
<div class="inner">
<p>我是什么颜色</p>
</div>
</div>
.outer { color: red; }
.inner { color: blue; }
p 是蓝色,因为 .inner 在红色和 p 之间断了链。想让它变红,要么给 p 直接设红,要么把 .inner 的蓝色去掉,或者给 p 写 color: inherit,它会继承 .inner 的蓝色,再往上就够不到了。
小结
继承让文字类的样式只用写一次,省事;盒模型类的样式不继承,各管各的。记住两条,继承的值优先级最低,一条直接声明就能覆盖;想要继承用 inherit,想重置用 initial 或 unset。下一篇进入整个 CSS 最重要的模型,盒模型。