继承

CSS 播客 - 第 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 属性会被继承。下面列出了默认继承的所有属性(摘自所有 CSS 属性的 W3 参考文档),供您参考:

继承的运作方式

默认情况下,每个 HTML 元素都有每个 CSS 属性,并且每个 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 样式获得了一些额外的属性,会发生什么情况?系统只会应用为 margincolor 设置的规则。

/* 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;
}

检查您的理解情况

测试您对继承的知识

以下哪些属性默认会被继承?

animation
动画不会向子项传递。
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

哪个值的行为像 inherit,除非没有要继承的内容,然后才会像 initial 一样?

reset
值无效,请重试!
unset
🎉
superset
值无效,请重试!

资源