层叠与继承
基于 CSS 现代标准 · 核于 2026-06
速查
- 层叠裁决四步,逐步定不了才看下一步:① 来源与重要性 → ②(层叠层)→ ③ 特异性 → ④ 书写顺序
- 普通声明来源由弱到强:浏览器(UA)< 用户 < 作者(你写的)
!important反转来源顺序:作者!important< 用户!important< 浏览器!important- 完整优先级(低→高):UA 普通 → 用户普通 → 作者普通 → 行内普通 → 动画 → 作者
!important→ 用户!important→ UA!important→ 过渡 - 动画(
@keyframes)压过一切普通声明;过渡(transition)优先级最高,连!important都压 !important是「逃生舱」不是常规手段——优先用@layer和:where()管理优先级- 没有任何规则命中某属性时:可继承属性(color/font 等)取父级计算值,否则用属性初始值
- 五个全局关键字:
inherit(强制继承父值)、initial(属性初始值)、unset(继承属性当 inherit、否则当 initial)、revert(回退到低来源的值)、revert-layer(回退到上一层叠层的值)
层叠:冲突裁决的四个阶段
「层叠」(cascade)是 CSS 名字里那个 C,指多条规则命中同一元素同一属性时决出唯一胜者的算法。它分四个阶段,像漏斗一样逐级筛选——上一阶段能分出胜负就停,分不出才进入下一阶段:
- 来源与重要性(origin & importance)——样式从哪来、带不带
!important; - 层叠层(cascade layers)——作者样式内部按
@layer排序(下一页专讲,这里先略); - 特异性(specificity)——选择器谁更具体(见 上一页);
- 书写顺序(order of appearance)——以上全平时,后写的赢。
注意顺序:来源与重要性在最前,比特异性更先决出。所以一条来自浏览器默认样式表、特异性再高的规则,也压不过你写的任意一条普通作者规则——因为「作者来源」整体就比「UA 来源」高一档。
第一阶段:来源与重要性
CSS 声明按「从哪来」分三种来源,普通声明(不带 !important)的优先级由低到高:
| 来源 | 是什么 | 普通声明优先级 |
|---|---|---|
| 浏览器(user-agent) | 浏览器内置默认样式(<h1> 默认大字号等) | 最低 |
| 用户(user) | 用户在浏览器里设的偏好、用户样式表、扩展注入 | 中 |
| 作者(author) | 你写的 CSS(外链 / <style> / 行内) | 最高 |
这解释了日常现象:你写的 h1 { font-size: 2rem } 总能盖过浏览器默认的 <h1> 字号——作者来源天然高于 UA 来源。
!important 把来源顺序倒过来
当声明带 !important,它进入一个独立的、更高的重要性档,而且这一档里来源顺序整个反转:
普通声明: UA < 用户 < 作者 (作者最强)
!important: 作者 < 用户 < UA (UA 最强,完全反转)为什么反转?这是为用户兜底无障碍:如果某个用户因视力问题,用浏览器设置强制放大字体(用户 !important),网站作者就不该能用自己的 !important 把它再压回去——所以用户 !important 必须高于作者 !important。
把动画与过渡塞进来:完整优先级阶梯
除了来源,激活中的动画与过渡也有特殊档位。把所有情况拼起来,从低到高的完整优先级是:
| 档位(低 → 高) | 说明 |
|---|---|
| 1. UA 普通声明 | 浏览器默认 |
| 2. 用户普通声明 | 用户偏好 |
| 3. 作者普通声明 | 你写的普通样式(含分层 / 未分层,见下页) |
4. 行内 style(普通) | 元素 style="" |
5. 动画 @keyframes | 激活的关键帧动画,压过以上所有普通声明 |
6. 作者 !important | 你写的 !important |
7. 用户 !important | 用户的 !important |
8. UA !important | 浏览器的 !important |
| 9. 过渡 transition | 最高,连 !important 都能压 |
为什么动画 / 过渡能压 !important
动画和过渡正在「进行时」,它们的本职就是逐帧改变视觉状态。如果一条 !important 能在动画中途把属性钉死,动画就会卡住、抖动。所以规范让激活中的过渡优先级排在最顶(动画稍低,但仍高于所有普通声明)——保证视觉过渡顺滑。这也意味着:用 !important 去「锁」一个正在过渡的属性,是锁不住的。
第四阶段:书写顺序
当来源、层、特异性全部打平,最后写的声明获胜。无论是同一文件里靠后的规则、靠后加载的 <link>,还是同一声明块里重复的属性,都遵循「后来居上」:
.alert {
color: orange;
}
.alert {
color: crimson; /* 同特异性,后写 → 最终 crimson */
}!important:逃生舱,不是常规工具
!important 能赢,但它破坏了层叠的可预测性:一旦用了,下次想覆盖就只能再来一个 !important,迅速演变成「!important 军备竞赛」,整套样式失控。
什么时候可以用:
- 覆盖无法修改的第三方内联样式(如某些 widget 用 JS 写死了
style); - 工具类 / 原子化 CSS 框架里,明确希望「这个类一锤定音」的场景(且框架已统一管理)。
什么时候别用:日常组件样式覆盖。现代 CSS 给了两个更优雅的替代:
MDN 的官方建议
MDN 明确建议:与其用 !important 覆盖外部样式,不如用 @import ... layer(name) 把外部样式表导入低优先级的层。这是 2026 年管理样式优先级的首选范式。
继承:层叠之外的「兜底」
层叠负责「多条规则冲突时选谁」。但如果没有任何规则命中某元素的某属性呢?这时轮到继承与初始值兜底。
CSS 属性分两类:
- 可继承属性:未显式赋值时,自动取父元素的计算值。多为文字排版相关:
color、font-family、font-size、line-height、letter-spacing、visibility、list-style等。 - 非继承属性:未赋值时,取该属性在规范里定义的初始值(而非「父级的值」)。多为盒模型 / 布局相关:
margin、padding、border、width、height、background等。
body {
color: #333;
border: 1px solid red;
}
/* <body> 里的 <p> 没写任何样式时: */
/* color → 继承得到 #333(可继承) */
/* border → 用初始值 none(非继承,不会继承红框)*/「直接命中」永远压过「继承而来」
继承值是最弱的值。只要有任何一条规则直接命中该元素的该属性(哪怕特异性极低、哪怕来自 UA 默认样式表),它就会盖过从父级继承来的值。所以「父级设了 color 但子元素颜色不对」时,先查是不是有别的规则直接命中了子元素。
五个全局关键字:手动控制继承与回退
任何 CSS 属性都能接收这五个「CSS 通用关键字」,用来精确控制取值来源:
.demo {
color: inherit; /* 强制取父元素的计算值——让非继承属性也继承 */
margin: initial; /* 重置为该属性的规范初始值(margin 的初始值是 0) */
padding: unset; /* 可继承属性→当 inherit;非继承属性→当 initial */
border: revert; /* 撤销作者样式,回退到更低来源(用户/UA)的值 */
display: revert-layer; /* 回退到「上一个层叠层」里该属性的值 */
}逐个说清,它们的差别全在「回退到哪里」:
| 关键字 | 取什么值 | 典型用途 |
|---|---|---|
inherit | 父元素该属性的计算值 | 让 border、background 等非继承属性显式继承父级 |
initial | 该属性在 CSS 规范里定义的初始值(不是浏览器默认!) | 把属性「清零」到规范基线 |
unset | 可继承属性 → 同 inherit;非继承 → 同 initial | 一键「擦掉作者设定、回到自然状态」 |
revert | 回退到更低来源(用户 / 浏览器)会产生的值 | 撤销作者样式、保留浏览器默认外观 |
revert-layer | 回退到前一个层叠层里该属性的值 | 在 @layer 中「撤销本层、露出下层」(见下页) |
initial ≠ 浏览器默认外观
最常见的误解:以为 display: initial 会让 <div> 回到 block。其实 display 的规范初始值是 inline,所以 div { display: initial } 会把 div 变成 inline!想「恢复浏览器默认外观」应该用 revert(回退到 UA 样式表的 display: block),而不是 initial。initial 给的是规范定义的初始值,常与直觉里的「默认」不同。
unset 与 revert 也别混:
/* 假设 UA 给 <a> 设了 color: blue(蓝色链接) */
a {
color: red;
} /* 作者样式 */
.reset-unset {
color: unset; /* color 可继承 → 取父级 color,可能是黑色正文色 */
}
.reset-revert {
color: revert; /* 撤销作者样式 → 回到 UA 的蓝色 */
}unset 走「继承/初始值」逻辑,revert 走「回退低来源」逻辑——前者可能露出父级文字色,后者会露出浏览器的蓝色链接。
小结
层叠是「来源与重要性 → 层 → 特异性 → 书写顺序」的四级漏斗,!important 把来源反转、动画与过渡享有最高档;没规则命中时由继承(可继承属性)或初始值兜底,五个全局关键字让你手动选择回退方向。其中第二阶段「层叠层」的威力——能让低特异性样式稳赢高特异性样式——值得单独一页:@layer 级联层实战。