CSS Podcast - 005:继承
假设您刚刚编写了一些 CSS 来使元素看起来像按钮。
<a href="http://example.com" class="my-button">I am a button link</a>
.my-button { display: inline-block; padding: 1rem 2rem; text-decoration: none; background: pink; font: inherit; text-align: center; }
然后,您向内容文章添加了一个链接元素,其 class
值为 .my-button
。不过,现在有一个问题, 文字的颜色不是您预期的颜色。这是如何发生的?
如果您未指定某些 CSS 属性的值,这些属性会沿用父元素的相应属性值。 对于此按钮,它从以下 CSS 继承了 color
:
article a { color: maroon; }
在本课中,您将了解出现这种情况的原因,以及继承如何成为一项强大的功能,帮助您减少 CSS 编写量。
继承流程
不妨看看以下 HTML 代码段,了解继承的运作方式:
<html> <body> <article> <p>Lorem ipsum dolor sit amet.</p> </article> </body> </html>
根元素 (<html>
) 不会继承任何内容,因为它是文档中的第一个元素。 在 HTML 元素上添加一些 CSS,它便会开始向下级联到文档中。
html { color: lightslategray; }
默认情况下,其他元素会继承 color
属性。html
元素具有 color: lightslategray
,因此所有可以继承颜色的元素现在都将具有 lightslategray
的颜色。
body { font-size: 1.2em; }
p { font-style: italic; }
只有 <p>
会显示斜体文本,因为它是嵌套最深的元素。 继承仅向下流动,不会返回到父元素。
哪些属性默认会继承?
并非所有 CSS 属性都默认继承,但有很多属性是默认继承的。为供参考,以下是默认继承的属性的完整列表,摘自所有 CSS 属性的 W3 参考资料:
- 方位角
- border-collapse
- border-spacing
- caption-side
- 颜色
- cursor
- direction
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- 字体
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- 孤儿
- 报价
- text-align
- text-indent
- text-transform
- 公开范围
- white-space
- 寡妇
- word-spacing
继承的运作方式
默认情况下,每个 HTML 元素都具有每个 CSS 属性,并定义了初始值。初始值是一种不继承的属性,如果级联无法计算相应元素的属性值,则会显示为默认值。
可以继承的属性会向下级联,子元素将获得表示其父元素值的计算值。这意味着,如果父元素的 font-weight
设置为 bold
,则所有子元素都将以粗体显示,除非它们的 font-weight
设置为其他值,或者用户代理样式表为该元素设置了 font-weight
值。
如何显式继承和控制继承
继承可能会以意想不到的方式影响元素,因此 CSS 提供了相关工具来帮助解决此问题。
inherit
个关键字
您可以使用 inherit
关键字让任何属性继承其父元素的计算值。 使用此关键字的一种有效方式是创建例外情况。
strong { font-weight: 900; }
此 CSS 代码段将所有 <strong>
元素的 font-weight
设置为 900
,而不是默认值 bold
(相当于 font-weight: 700
)。
.my-component { font-weight: 500; }
.my-component
类将 font-weight
设置为 500
。 如需使 .my-component
内的 <strong>
元素也 font-weight: 500
,请添加:
.my-component strong { font-weight: inherit; }
现在,.my-component
内的 <strong>
元素的 font-weight
将为 500
。
您可以明确设置此值,但如果您使用 inherit
,并且 .my-component
的 CSS 在未来发生变化,您可以保证 <strong>
会自动保持最新状态。
initial
个关键字
继承可能会导致元素出现问题,而 initial
可为您提供强大的重置选项。
您之前了解到,每个属性在 CSS 中都有一个默认值。initial
关键字会将属性设置回初始默认值。
aside strong { font-weight: initial; }
此代码段将移除 <aside>
元素内所有 <strong>
元素的粗体权重,并将其改为正常权重(初始值)。
unset
个关键字
如果属性默认继承,unset
属性的行为会有所不同。如果某个属性默认继承,则 unset
关键字将与 inherit
相同。 如果该属性默认不继承,则 unset
关键字等于 initial
。
记住哪些 CSS 属性是默认继承的可能很困难,在这种情况下,unset
会很有帮助。 例如,color
默认情况下会继承,但 margin
不会,因此您可以编写以下代码:
/* Global color styles for paragraph in authored CSS */ p { margin-top: 2em; color: goldenrod; } /* The p needs to be reset in asides, so you can use unset */ aside p { margin: unset; color: unset; }
现在,margin
已移除,color
恢复为继承的计算值。
您还可以将 unset
值与 all
属性搭配使用。 回到前面的示例,如果全局 p
样式添加了其他几个属性,会发生什么情况?系统将仅应用为 margin
和 color
设置的规则。
/* Global color styles for paragraph in authored CSS */ p { margin-top: 2em; color: goldenrod; padding: 2em; border: 1px solid; } /* Not all properties are accounted for anymore */ aside p { margin: unset; color: unset; }
如果您将 aside p
规则更改为 all: unset
,那么无论将来对 p
应用什么全局样式,这些样式都将始终处于未设置状态。
aside p { margin: unset; color: unset; all: unset; }
revert
个关键字
正如您在有关层叠的课程中所学到的,样式来自不同的来源:用户代理基本样式、用户偏好样式和您编写的样式。revert
关键字会撤消在与 revert
关键字相同的来源中设置的样式。
如果您已设置样式,但不想在某些情况下应用该样式,此功能非常有用。inherit
、initial
和 unset
用于指定如何计算样式的值,而 revert
仅用于指定您编写的其他样式不适用。
p { padding: 2em; } aside p { padding: revert; }
此代码段为 <p>
元素指定了内边距,但当 <p>
元素位于 <aside>
内时,它根本没有指定 padding
。而是恢复为用户偏好样式(如果已设置)或用户代理基本样式。
revert-layer
个关键字
级联层提供了一种有用的方式来整理样式,并确定级联的作者来源中样式的优先级。revert-layer
关键字与 revert
类似,但它不是指定不应为属性应用任何作者样式,而只是撤消当前层中的样式。
如果您使用的是第三方界面库,一种有用的模式是将其导入到某个层中,并将所有替换项添加到优先级更高的层中。然后,您可以使用 revert-layer
移除替换项,这样系统就会改用界面库的默认值。
如果没有其他层为该属性指定值,则其行为将与 revert
类似,并使用来自较早来源的值。
检验您的掌握情况
测试您对继承的了解程度
默认情况下,以下哪些属性会被继承?
animation
font-size
color
text-align
line-height
哪个值的行为类似于 inherit
,除非没有可继承的内容,然后行为类似于 initial
?
reset
unset
superset