【CSS in Depth 2 精译_007】1.2 继承~1.3 特殊值

1.2 继承

除了层叠,还有一种给元素设置样式的方式:继承。经常有人把层叠与继承的概念弄混淆。它们虽然有关联,但也应该分辨清楚各自的特点。

如果一个元素的特定属性没有层叠值,则可能会继承某个祖先元素的样式值。在 <body> 元素上设置字体系列 font-family 是很常见的做法。之后其内部的所有元素都将继承该字体,省去了给每个元素手动指定的麻烦。图 1.8 展示了继承是如何沿着 DOM 树向下传播开来的:

图 1.8 被继承的属性从父节点顺着 DOM 树传递至后代节点
图 1.8 被继承的属性从父节点顺着 DOM 树传递至后代节点

然而,并非所有属性都会被继承。默认情况下通常只有那些特定的、我们希望看到的属性被继承下来,主要与文本相关,如:colorfontfont-familyfont-sizefont-weightfont-variantfont-styleline-heightletter-spacingtext-aligntext-indenttext-transformwhite-space 以及 word-spacing

此外也包括一些其他属性,比如列表相关的属性:list-stylelist-style-typelist-style-position 以及 list-style-image;表格边框相关的属性 border-collapseborder-spacing 也会被继承。注意,这些属性控制的是表格的边框行为,表格元素边框以外的常规属性不受影响。(没人希望一个 <div> 元素将其边框样式传递给每一个后代元素吧。)虽然上面罗列的属性算不上最完整,但也基本够用了。

您可以在充分利用继承来设计页面样式,比如在 body 元素上设置字体,让后代元素继承这些样式(如图 1.9 所示)。

图 1.9 给 body 设置 font-family,让其后代元素继承该样式

图 1.9 给 body 设置 font-family,让其后代元素继承该样式

将如下代码添加到您的示例样式表顶部,让继承的样式生效。

代码清单 1.13 将 font-family 应用到父元素

body {
  font-family: sans-serif; /* 被继承的属性值会传递到后代元素上 */
}

这样添加到 body 的样式会在整个页面生效。若将样式指定到特定元素,则该样式只会被其后代元素继承。被继承的样式会逐级传到后代元素,直到被某个层叠值覆盖。

使用开发者工具

被继承与覆盖的属性值在错综复杂的嵌套结构下会很快变得难以追踪。如果您还不熟悉浏览器的开发者工具,请务必养成使用它们的习惯。

DevTools 开发者工具可以精准查看哪些元素应用了哪些样式规则,以及为什么呈现这些样式。层叠和继承都是抽象的概念;而 DevTools 是目前已知最好的样式追踪手段。在一个页面元素上单击鼠标右键,选择弹出菜单中的 检查(Inspect)或 检查元素(Inspect Element)就能打开该工具。如图 1.x 所示。

图 1.x 浏览器的 DevTools 开发工具是查看元素样式的最佳方式

图 1.x 浏览器的 DevTools 开发工具是查看元素样式的最佳方式

样式检查器显示了目标元素的每个选择器,并按优先级进行排列。选择器样式的下方是继承的所有属性。元素所有的层叠规则与继承样式都一目了然。

还有很多功能细节可以帮助开发人员弄清目标元素当前样式的来龙去脉。靠近顶部的样式会覆盖掉下方的样式。被覆盖的样式会被划掉;右侧给出了每个规则集的样式表名称与行号,以便快速定位到源代码位置。这样就能准确知晓哪个元素继承了哪些样式,以及这些样式的具体来源。此外,还可以在顶部的 Filter 筛选框中筛选出目标样式,同时隐藏其他无关内容。


1.3 特殊值

还有一些特殊的声明值,可以赋给元素的任意属性,以便更好地控制层叠,分别是:inheritinitialunsetrevert。下面逐一进行考察。

细心的您可能已经注意到了,代码清单 1.12 给出的超链接样式与平常略有不同,文字颜色由传统的蓝色改为了白色字体、蓝色背景。这么做正是为了演示上述关键字的效果。

1.3.1 inherit 关键字

有时,当继承的样式被层叠值中断后,又想让继承样式重新生效。此时可以使用 inherit 关键字来实现,强制目标元素从父元素继承所需样式。

假设要在示例页添加了一个浅灰色的页脚,页脚内有一些超链接,但不希望它们太显眼,毕竟页脚不是示例页的重点。这就要把页脚内的超链接设置为深灰色(如图 1.10 所示)。

图 1.10 继承灰色文本的使用条款链接

图 1.10 继承灰色文本的使用条款链接

代码清单 1.14 给出了此页脚的 HTML 结构。将其添加到页面末尾,即关闭标签 </body> 的前面。普通网页在页脚和页头之间会显示更多内容,这里方便演示就不展开了。

代码清单 1.14 带链接的页脚

<footer class="footer">
  &copy; 2023 Wombat Coffee Roasters &mdash;
  <a href="/terms-of-use">Terms of use</a>
</footer>

早些时候给示例页上所有的超链接都设置了一些样式,它们也将对《使用条款》的超链接生效。要让页脚内的链接变为灰色,需要用以下代码覆盖原有样式。

代码清单 1.15 inherit 值的应用

.footer {
  color: #666;  /* 页脚文本设置为灰色 */
  background-color: #ccc;
  padding: 15px 0;
  text-align: center;
  font-size: 14px;
}
.footer a {
  color: inherit;  /* 指定文字颜色从页脚继承 */
  background-color: transparent;  /* 覆盖蓝色背景为透明 */
  text-decoration: underline;
}

上述代码的第二个规则集用一个名为 inherit 的层叠值覆盖了页脚超链接本来的颜色。这样就继承了父元素 <footer> 的颜色。

这么做的好处是,一旦页脚的样式发生任何改动(例如修改第二个规则集,或者被其他样式覆盖),页脚超链接的样式也会同步跟进。例如,页脚文字在某些页面是较深的灰色,其中的超链接也会随之切换为深灰色。

此外,还可以使用 inherit 关键字来强制继承一个通常不会被继承的属性,比如边框或内边距,尽管在实际开发过程中鲜有用武之地。

1.3.2 initial 关键字

有时可能需要撤销某个元素的样式,正如代码清单 1.15 中撤销背景色那样的效果。此时就可以用关键字 initial 来实现目标。

每一个 CSS 属性都有一个初始值或默认值。如果将样式属性赋值为 initial,则可以将其手动设为该属性的默认样式,好比硬复位了该样式。

设置透明背景不要写成 background-color: transparent,而是使用 initial 值。根据以下代码更新样式。由于 transparent 是背景色属性 background-color 的初始值,最终效果将与上一段代码相同:

代码清单 1.16 initial 值的应用

.footer a {
  color: inherit;
  background-color: initial;  /* 将背景色重置为初始值 */
  text-decoration: underline;
}

这样做的好处是不必考虑太多:想移除一个元素的边框,使用 border: initial 即可;想让元素恢复为默认宽度,使用 width: initial 就搞定了。

可能您已经习惯了用 auto 值来实现诸如此类的重置效果;事实上使用 width: auto 确实也行,因为 width 的默认值本就是 auto

但值得注意的是 auto 并非所有属性的默认值,对许多属性而言,auto 值甚至是无效的。例如 border-width: autopadding: auto 就是无效样式,因此看不到任何效果。您也可以花时间钻研一下这些属性的初始值,但使用 initial 更简单。

注意

样式 display: initial 等价于 display: inline,并且无论加到什么元素上,都不会产生 display: block 的效果。这是因为 initial 会重置为该属性(property)的初始值,而不是该元素(element)的初始值; inline 才是 display 属性的默认值。在这种情况下,应该考虑使用关键字 revert

1.3.3 unset 关键字

关键字 inheritinitial 对于清除继承或非继承属性上设置的样式都非常有用。unset 关键字则是二者的结合:用于继承属性时,其值就是 inherit;用于非继承属性时,其值就是 initial

当然,您也可以分别使用 inheritinitial 来实现目标,但是 unset 用起来更简单,可以避免用错关键字。在示例的页脚上,您可以使用 unset 来修复超链接的字体及背景颜色。

代码清单 1.17 unset 值的应用

.footer a {
  color: unset;  /* 给能被继承的属性一个 inherit 值 */
  background-color: unset; /* 给不能被继承的属性一个 initial 值 */
  text-decoration: underline;
}

这样,文字颜色就设为了 inherit,使其能够继承页脚的灰色字体;而背景色设为了 transparent,它刚好是 background-color 属性的初始值。

注意:恢复链接的下划线样式仍然需要通过 text-decoration: underline 来实现。此时 unset 并不生效,因为 text-decoration 属性的初始值是 none 而非 underline 。请务必牢记:CSS 属性(CSS property)本身的初始值始终保持不变;它不受目标元素具体类型的影响。要“撤消”之前设置的 text-decoration 样式,需要用到另外一个关键字。

1.3.4 revert 关键字

关键字 initialunset 基本上可以覆盖包括作者样式和用户代理样式表在内的所有样式。如果只想覆盖此前设置的作者样式,而保留用户代理样式不变。这就是关键字 revert 的用法。

示例页脚中,如果将所有三个属性设为 revert,则超链接的样式将变为带下划线的蓝色文字(即浏览器默认样式);但我们想要的是灰色字体,因此在关键字的选择上应该更仔细:仅将 revert 应用到 text-decoration 属性上。按照代码清单 1.18 更新样式并查看最终效果。

代码清单 1.18 revert 值的应用

.footer a {
  color: unset;
  background-color: unset;
  text-decoration: revert; /* 撤销为用户代理样式 */
}

在本例中,这些关键字可能看起来有些多余,因为这些属性对您而言可能非常熟悉,直接给它们赋上需要的样式值即可;但是,当使用较新的 CSS 功能或遇到像 flexbox 这样、具有多个关键字的样式属性时,可能就没那么容易知晓其对应的默认值了。这时,这些关键字就派上用场了。此外,这么做还有一个额外的好处:可以巧妙地提醒今后的样式开发人员,您这里的意图旨在有效地撤消样式表中其他地方的样式。

警告

这些关键字都是普通的层叠值,意味着当优先级更高的其他选择器也指向同一个元素时,其样式值仍然可以被新样式覆盖。

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值