先记住这个答案
CSS 提供了几个特殊关键字来重置属性值。inherit 强制取父元素的计算值,哪怕这个属性本身不会自动继承。initial 把值还原到 CSS 规范里定义的初始值,注意这不是浏览器的默认样式。unset 相当于一个快捷方式:如果属性天然可继承就走 inherit,否则走 initial。面试时最常考的就是 initial 和浏览器默认值的区别。
inherit强制继承,连margin也行initial回规范初始值,不是浏览器默认unset按属性天性自动二选一revert才是回到浏览器默认样式
initial 为什么不等于浏览器默认样式
很多人以为 display: initial 会让 <div> 回到 block,但实际拿到的是 inline。因为 CSS 规范规定 display 的初始值就是 inline,是用户代理样式表(也就是浏览器内置的默认样式)给 <div> 设了 display: block。initial 跳过了用户代理样式表,直接回到规范定义。
initial 和 revertCSS/* 假设外层 div 没有额外样式 */
div.reset-initial {
display: initial; /* 结果是 inline,规范初始值 */
}
div.reset-revert {
display: revert; /* 结果是 block,浏览器默认样式 */
}
div.reset-unset {
display: unset; /* display 不可继承,等于 initial,结果是 inline */
}这三个关键字对 display 的效果完全不同。revert 才是"恢复到浏览器默认",而 initial 是"恢复到规范定义的初始值"。面试时说清楚这个区别,能体现你对层叠的理解不是停留在表面。
可继承和不可继承属性上的差异
CSS 属性分两类。color 和 font-size 这些天然可继承,子元素没声明时自动拿父元素的值。margin 和 padding 以及 border 和 display 这些不可继承,子元素没声明时用规范初始值。
unset 在两类属性上的表现CSS.parent {
color: red; /* color 可继承 */
border: 1px solid blue; /* border 不可继承 */
}
.child {
color: unset; /* 可继承 → 等于 inherit → 拿到 red */
border: unset; /* 不可继承 → 等于 initial → 回到 none */
}unset 的好处是不用记住每个属性是否可继承,它会自动选择合适的回退方式。配合 all: unset 可以一次性清除元素上的所有样式,对组件重置很有用。但要注意 all: unset 会把 display 也重置成 inline,通常还需要手动补上 display 的值。
容易答错的地方
- 把
initial当成浏览器默认样式 - 这是最高频的错误。
<div>写display: initial变成inline而不是block,因为block来自用户代理样式表,不是规范初始值。想回到浏览器默认样式要用revert。 - 以为
unset总是等于inherit - 只有可继承属性才走
inherit路径。对margin和padding这些不可继承属性,unset等于initial,回到规范初始值而不是父元素的值。
面试官还会怎么问?
revert-layer 和 revert 有什么不同?
revert 回退到上一个来源,比如从作者样式回退到用户代理样式。revert-layer 只回退到上一个 @layer,仍然留在同一个来源内。如果你用 @layer 管理组件库和业务样式的优先级,revert-layer 可以让某个属性回退到更早的层,而不是直接跳到浏览器默认样式。
all: unset 和 all: revert 哪个更适合做组件重置?
all: unset 把所有属性恢复到规范初始值或继承值,可能导致 <div> 变成 inline,列表失去样式。all: revert 恢复到浏览器默认样式,<div> 还是 block,<ul> 还有默认的列表样式。做组件重置通常用 all: revert 更安全。
inherit 取的是父元素的什么值?
取的是父元素的计算值,不是 CSS 源码里写的值。如果父元素写了 font-size: 2em,子元素通过 inherit 拿到的是换算后的像素值(比如 32px),不是 2em。百分比也一样,width: 50% 继承下来是计算后的具体像素值,不是百分比。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。