0%

CSS 层叠与继承

写在前面

CSS 是层叠样式表 (Cascading Style Sheets) 的缩写。要理解本节内容,我们首先需要搞清楚层叠的概念。与这个概念密切相关的还有“当某个元素同时拥有两种冲突的样式时,应该应用哪一种”的问题,也即优先级问题。我们还将了解哪些父元素的样式会被子元素继承,哪些则不会

最后我们总结精炼了一些样式优先级的法则

层叠

样式表层叠,一种简单的理解是对于某个元素,其后书写的样式将会覆盖前面的样式

1
2
3
4
5
6
7
8
p {
font-size: 17px;
font-family: "unserif" // 这条规则将会起作用
}

p {
font-size: 20px; // 这条规则将会起作用
}

优先级

浏览器会根据优先级来决定当多个规则有不同选择器对应相同的元素的时候需要使用哪个规则

基本的原则是:一个更具体的元素选择器将拥有更加高的优先级

1
2
3
<p class="special">
一个类名为 special 的段落元素。
</p>

对于上面的 <p>,仅有第二个规则会被应用

1
2
3
4
5
6
7
p {
color: red;
}

.special {
color: blue;
}

继承

我们通过以下例子来分析可以继承和不可继承的样式

See the Pen inheritance_1 by KiritoShaw (@KiritoShaw) on CodePen.

先分析 <body> 的样式,显然 font-size 是可以继承的;width 是不可以继承的

<article>borderpadding 不可以被继承 (margin 也是同样的道理),而背景颜色 background-color 和字色 color 可以被标题 <h1> 和段落元素 <p> 继承

<strong> 元素的字色被子元素 <em> 继承

事实上,很多默认继承与不继承的方式都是符合常理的。border 显然不应该继承,否则每个后代元素都会出现边框,这显然是不合理的;背景颜色 background-color 可以继承也理所应当,否则后代元素的默认背景颜色将变成白色,显得格格不入

See the Pen inheritance_2 by KiritoShaw (@KiritoShaw) on CodePen.

提示:这里的选择器用法如有不懂,请阅读 Reference 中的参考资料

在字号样式 font-size 中,存在一种特殊的“继承”形式,它是通过值的单位 em 来控制的,意为相对于元素父元素 font-size 的倍数

设置 <ul>font-size: 1.4em,则每嵌套一次列表,列表的字号都会相对于父元素倍增,正如这里的 Item 3 -> Item 3.1 -> Item 3.1.1 所示

与之相关的还有另一个单位 rem,此时元素的字号大小是相对于根元素的字号而言的,嵌套并不会产生指数倍增效果

你或许还关注到 Item 3.1.2 应用了声明 font-size: initial,这涉及到了控制继承的问题。这里 initial 表示将应用于选定元素的属性值设置为该属性的初始值

此外还有四种特殊的通用属性值:

  1. inherit 设置该属性会使子元素属性和父元素相同。实际上,就是“开启继承”
  2. revert (en-US) 将应用于选定元素的属性值重置为浏览器的默认样式,而不是应用于该属性的默认值。在许多情况下,此值的作用类似于 unset
  3. revert-layer (en-US) 将应用于选定元素的属性值重置为在上一个层叠层中建立的值
  4. unset 将属性重置为自然值,也就是如果属性是自然继承那么就是 inherit,否则和 initial 一样

总结与补充

  1. 优先级相同:按资源顺序,后 > 前
  2. 优先级不同:
    • ID 选择器 > 类选择器 > 类型选择器
    • 具体选择器 > 抽象选择器
    • 内联样式 > 所有选择器
    • !important 拥有最高优先级

关于 !important,感兴趣的读者可以阅读 层叠与继承 #!important | MDN

Reference

  1. 层叠与继承 | MDN
  2. :nth-child - CSS | MDN
  3. :nth-of-type - CSS | MDN
  4. CSS选择第二个子元素 - 编程猎人