继承

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 属性的 W3 参考

继承的工作原理

每个 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 样式获得了另外几个属性会发生什么?只有为 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
不是有效值,请重试!

资源