先记住这个答案
all 是个简写属性,一次性给除 direction、unicode-bidi 以外的所有 CSS 属性设同一个值,自定义属性也不在它的范围里。它只接受几个全局关键字。all: unset 的规则是:可继承的属性,比如 color、font-size,改成继承父元素;不可继承的属性,比如 display、margin、border,回到规范里的初始值。all: revert 是把当前作者写的样式全部撤掉,退回浏览器默认样式。最直观的区别是 div 写 all: unset 会变成 inline,写 all: revert 还是 block。
all不重置方向和自定义属性unset:可继承的继承,不可继承的回初始值revert:退回浏览器默认样式all: unset会重置display
同一个元素用三个关键字
同一个父元素下放三个 h1,分别用三个关键字,差别一眼就能看出来。
unset、revert、initial 的效果HTML<style>
.parent { color: red; font-size: 14px; }
.unset { all: unset; } /* 红色 14px,display 变成 inline,没有加粗和外边距 */
.revert { all: revert; } /* 红色,但字号、加粗、外边距回到浏览器给 h1 的默认值 */
.initial { all: initial; } /* 不继承父元素:颜色回到默认的黑色,字号 16px,inline */
</style>
<div class="parent">
<h1 class="unset">unset</h1>
<h1 class="revert">revert</h1>
<h1 class="initial">initial</h1>
</div>.unset 的 color、font-size 可继承,所以跟着父元素变红、变成 14px;display、margin、font-weight 在 h1 上本来是浏览器默认样式表给的,现在回到初始值,于是变成行内、没外边距、不加粗。
.revert 撤掉的只是作者样式,浏览器默认样式表里 h1 的 display: block、font-size: 2em、font-weight: bold 都还在。颜色是红的,因为浏览器默认样式没给 h1 设颜色,color 本来就继承父元素。
.initial 连继承都不要了,color 回到初始值,一般就是黑色,font-size 回到 medium,也就是 16px。
初始值和浏览器默认样式不是一回事
很多人以为「重置」就是回到元素的默认样子,这里要分清两个概念。初始值是规范里每个属性自己的默认值,和元素无关,display 的初始值对所有元素都是 inline。浏览器默认样式是浏览器内置的一张样式表,给 div 写了 display: block,给 button 写了边框和背景。
unset 和 initial 退到的是初始值,会连浏览器默认样式一起抹掉。revert 退到的是浏览器默认样式,元素保留原本的样子。
revert-layer- 用了
@layer的项目还有revert-layer,它只退回到上一个层叠层里的样式,不会一路退到浏览器默认。组件库里想「去掉本层的覆盖、用基础层的样式」时就用它。
实际项目里怎么用
最常见的场景是把原生 button 的样式清干净,做成一个看起来像链接的按钮。这时 all: unset 很顺手,但会一起清掉几样有用的东西:cursor 变回默认箭头,outline 回到初始值 none,键盘聚焦时看不到焦点框,display 变成 inline。所以 all: unset 后面要补上 cursor: pointer 和 :focus-visible 的焦点样式,否则会有可访问性问题。
另一个场景是嵌入第三方组件或 Web Components 时,用 all: initial 挡住外部页面继承进来的字体、颜色,让组件样式不受宿主页面影响。
容易答错的地方
- 以为
all会重置 CSS 变量 - 自定义属性不受
all影响。父元素定义的--color,子元素写了all: unset照样能用var(--color)读到。 - 以为
all: unset能保留元素原本的样子 - 它会抹掉浏览器默认样式,
div变行内,ul没了左侧缩进,button没了边框和背景。想保留原生样子只去掉作者样式,用revert。 - 以为
all会改direction direction和unicode-bidi被故意排除在外,因为文字方向往往由 HTML 的dir属性决定,重置它会把 RTL 页面的文字顺序搞乱。
面试官还会怎么问?
all: unset 和 all: initial 在实践中差在哪?
差在可继承属性上。unset 让字体、颜色继续从父元素继承,元素还能融入周围的文字;initial 把它们也回到初始值,文字会变成浏览器初始字体和黑色,嵌在深色背景里可能直接看不见。
all 写在样式表里,它自己的优先级怎么算?
all 就是一个普通声明,和其他声明一样参与层叠。写在它后面、或者选择器优先级更高的声明,会覆盖它展开出来的某个属性。所以常见写法是先写 all: unset,下面再补需要的属性。
用 all: revert 做样式隔离可靠吗?
只能隔离作者样式。用户样式表和浏览器默认样式还在,而且它挡不住继承进来的值。需要严格隔离时,用 Shadow DOM 更可靠。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。