08继承与层叠
本章第 01 课说过,CSS 有两个灵魂概念:继承(Inheritance)和层叠(Cascade)。 继承解释了「为什么给 body 设一次字体,全站文字都跟着变」; 层叠回答了「同一个元素被好几条规则同时点名,到底听谁的」。 这一课把这两个机制讲透——下一课的选择器优先级计算,只是层叠的其中一环。
一、什么是继承:孩子自动拿到父级的某些属性
继承(Inheritance):给父元素设了某些属性,
它的子元素、孙元素……整个后代都会自动拿到同样的值,
不用一个个去设。这就是为什么老手只在 body 上写一次
color 和 font-family,全站文字就统一了。
但注意:不是所有属性都继承。 给父元素加边框,孩子们并不会每人都长一个边框——否则页面早乱套了。
.parent 设了 color / font-size / line-height,两个孩子全跟着变;而 border / padding 只有父级自己有。把 .parent 的 color 改成 #4E7A52,看两段文字一起变绿孩子 A:什么都没设,文字样式却和父级一样(继承了)
孩子 B:注意看——我没有自己的边框(边框不继承)
二、哪些属性继承、哪些不继承
不用死记硬背整张表,记住一句话就够: 和「文字排版」相关的属性才继承,和「盒子占位」相关的都不继承。 道理很直觉——文字样式当然希望全篇统一;而盒子尺寸边距各有各的算盘,绝不能乱传。
| 分类 | 属性 | 继承吗 | 为什么 |
|---|---|---|---|
| 字体类 | font-family / font-size / font-weight / font-style | ✓ 继承 | 全站字体统一,设一次就够 |
| 文本类 | color / line-height / text-align / text-indent / letter-spacing | ✓ 继承 | 段落排版跟着整体风格走 |
| 其他 | visibility / cursor / list-style | ✓ 继承 | 父级隐藏,孩子当然一起藏 |
| 盒子类 | width / height / margin / padding | ✗ 不继承 | 每个盒子的尺寸边距各管各的 |
| 边框背景 | border / background / border-radius | ✗ 不继承 | 不然每个孩子都复制一套边框背景,页面没法看 |
| 布局类 | display / position / float / flex | ✗ 不继承 | 布局方式逐元素单独指定 |
三、四个控制词:inherit / initial / unset / revert
CSS 给所有属性预备了四个通用关键字, 用来精确控制「这个值从哪来」:
| 关键字 | 含义 | 典型用途 |
|---|---|---|
| inherit | 强制继承:不管这属性天生继不继承,都拿父级的值 | 让链接、按钮继承父级文字颜色 |
| initial | 回到属性的「规范初始值」(如 color 的初始值是黑色) | 清掉自己写过的某条声明 |
| unset | 自动二选一:天生继承的属性 = inherit,其余 = initial | 「恢复自然状态」的懒人键 |
| revert | 回滚到浏览器默认样式(用户代理样式表那一层) | 撤销作者样式,恢复浏览器原样 |
.force 用 border: inherit 强行继承了父级的金框;奇效二:.plain-link 用 color: unset + text-decoration: unset 变回普通文字。把 inherit 改成 initial,看子级边框消失unset 是最常用的那个:它「懂规矩」——
该继承的继承、该归零的归零。拿不准用哪个时,先试 unset。四、all 属性:一键重置的「核弹按钮」
all 是一个简写属性,代表「除了 direction 和 unicode-bidi
之外的所有属性」。给它一个控制词,等于一次性把几百个属性全部设置。
最常见的用法是 all: unset——把元素剥成「裸奔状态」,
做自定义按钮、重置第三方组件时特别好用。
all: unset 剥光,只剩纯文字,再从零定制。把 all: unset 那行删掉,看右边按钮瞬间「穿回衣服」all: unset 连 cursor、
display 都会一起清掉——剥光之后记得把需要的(比如
cursor: pointer)亲手补回来,否则按钮连「手型」都没了。五、层叠三要素:听谁的,看这三条
同一个元素的同一个属性,被好几条规则同时点名时, 层叠(Cascade)按下面三条依次裁决—— 前一条分出胜负,后面就不用比了:
| 顺序 | 比什么 | 规则 |
|---|---|---|
| ① | 来源与重要性 | !important 声明 > 作者样式(你写的)> 浏览器默认样式 |
| ② | 优先级(Specificity) | 行内样式 > id 选择器 > 类选择器 > 元素选择器——详细打分规则见 09 选择器进阶 |
| ③ | 书写顺序 | 前两条打平手时,后写的赢(后来者居上) |
.btn-b 写在后面所以生效,按钮是砖红色。把 .btn-b 整块剪切到 .btn-a 前面,看按钮变成金色——顺序即胜负当前生效:后写的那条规则
六、!important:能掀桌子的王牌,别乱打
在声明后面加 !important,这条声明就跳到了层叠第一关的顶端:
压过一切普通声明,包括行内样式。
它合理的使用场景很窄——覆盖第三方组件库的样式、覆盖你改不了的行内样式。
滥用它会引发「军备竞赛」:你加一个 !important,
下次别人只能再加一个更高的来压你,最后满屏感叹号,谁也动不了谁。
style(层叠里行内优先级极高),但右边被 !important 强行压成了砖红。把 !important 删掉,右边立刻变回行内的绿色!important 就不用。
样式不生效时,先去 DevTools 查优先级(09 课教你算分),
别第一时间掏王牌——掏多了,代码就没人敢维护了。七、本章小结
- 继承(Inheritance):后代自动拿到父级的某些属性,只向下传。文字排版类属性继承,盒子布局类不继承。
- 四个控制词:
inherit强制继承、initial回初始值、unset自动二选一、revert回浏览器默认。 all: unset一键剥光元素所有样式,是定制按钮 / 重置组件的利器,剥完记得补cursor。- 层叠(Cascade)三步裁决:先比来源与重要性,再比优先级,打平才比书写顺序——后写的赢。
!important能压住行内样式,是掀桌王牌;合理场景只有覆盖第三方 / 行内样式,滥用必成「军备竞赛」。- 优先级的详细打分(行内 > id > 类 > 元素),下一课 09 选择器进阶 见分晓。