使用 CSS all: unset 移除原生元素样式
你一定遇到过这种情况:想要一个自定义样式的按钮,于是开始一个属性一个属性地覆盖浏览器默认样式。border: none、background: none、padding: 0、cursor: pointer。它能用,但感觉不对劲——就像在和用户代理样式表玩打地鼠游戏。
有一种更干净的方法:CSS 的 all 属性。具体来说,是 all: unset。本文将解释它的确切作用、何时使用,以及它会悄悄破坏什么——包括键盘用户依赖的焦点样式。
核心要点
all: unset一次性重置所有 CSS 属性:可继承属性从父元素继承,而不可继承属性恢复为 CSS 规范定义的初始值(而非浏览器默认值)。- 它会移除焦点环,因此请始终使用
:focus-visible恢复可见性,以保护键盘可访问性。 all: unset和appearance: none解决的是不同的问题。表单控件通常两者都需要:一个针对层叠,一个针对操作系统级别的渲染。- 避免在布局容器上使用,或仅需更改少数几个属性时使用——它是一种”粗暴”的工具,最好仅用于完整的组件重置。
all: unset 在 CSS 层叠中的实际作用
all 属性是一个简写属性,可以一次性设置所有 CSS 属性,但 unicode-bidi、direction 和 CSS 自定义属性除外。根据 MDN,all: unset 对每个属性应用以下规则:
- 如果属性是可继承的(如
color、font-size、line-height),它将从父元素继承。 - 如果属性是不可继承的(如
display、border、background、padding),它将恢复为 CSS 规范定义的初始值。
这是一个关键区别。all: unset 并不会恢复浏览器默认值。它将不可继承属性重置为其规范默认值——这并不是同一回事。一个使用 all: unset 样式的 <button> 看起来不会像一个普通的浏览器按钮。它将完全失去其 display、appearance、边框、内边距和焦点环。
all 属性的四个取值
| 取值 | 作用 |
|---|---|
unset | 可继承属性继承自父元素;不可继承属性恢复为其初始值 |
initial | 每个属性都重置为 CSS 规范默认值(忽略继承) |
revert | 将属性回滚到没有当前作者样式表时的值,通常会恢复浏览器默认值 |
inherit | 强制每个属性都从父元素继承 |
对于自定义 UI 组件,all: unset 通常是你想要的。如果你需要撤销自己样式表的覆盖同时保留浏览器默认值,则 all: revert 是更好的选择。
正确地重置一个按钮
下面是一个实用的按钮重置模式,可以在不破坏可访问性的前提下移除原生元素样式:
.button-reset {
all: unset;
/* Restore safe defaults */
display: inline-block;
cursor: pointer;
box-sizing: border-box;
/* Your custom styles */
padding: 0.5rem 1rem;
background: #0070f3;
color: white;
border-radius: 4px;
}
/* Always restore focus visibility for keyboard users */
.button-reset:focus-visible {
outline: 2px solid #0070f3;
outline-offset: 3px;
}
:focus-visible 规则是不可妥协的。all: unset 会移除浏览器的默认焦点环,这意味着键盘用户失去了他们唯一的视觉指示器,无法判断焦点在哪里。使用 :focus-visible 恢复它遵循浏览器对何时应显示可见焦点指示器的启发式判断,通常是在键盘导航期间显示,而不会在鼠标点击时总是显示轮廓。
Discover how at OpenReplay.com.
all: unset 与 appearance: none——它们并不相同
这是一个常见的混淆点。appearance: none 仅移除表单控件的原生操作系统级渲染——即让 <select> 看起来像 macOS 下拉框或 Windows 组合框的平台特定外观。它不会触及布局、间距、颜色或任何其他 CSS 属性。
all: unset 是一种广泛的 CSS 层叠重置。它会影响所有内容(除上文提到的少数例外)。
对于像 <select>、<input> 和 <textarea> 这样的原生表单控件,你通常两者都需要:
select {
all: unset;
appearance: none; /* Removes OS-level control rendering */
display: block;
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
background: white;
cursor: pointer;
}
select:focus-visible {
outline: 2px solid #0070f3;
outline-offset: 2px;
}
请注意,一些浏览器还需要 -webkit-appearance: none 前缀,以便在旧版本的 Safari 和 iOS 上获得完整的跨浏览器支持。all 和 appearance 在现代浏览器中的支持都很强大。
何时不要使用 all: unset
避免在只需更改少数几个属性的元素上使用 all: unset。它是一种粗暴的工具。如果你只是想移除按钮的背景和边框,请直接针对这些属性——这样不太可能产生意想不到的副作用。
也要避免在容器元素上使用它。重置 flex 或 grid 父元素的 display 会无声地使你的布局崩塌。
结论
all: unset 是从按钮、链接和表单控件中剥离原生元素样式的强大快捷方式——但它会重置所有内容,包括你可能想保留的属性。使用它之后,始终要恢复 display、box-sizing、cursor,特别是 :focus-visible。当处理具有操作系统级渲染的原生表单控件时,将其与 appearance: none 配合使用。谨慎使用,它是现代 CSS 中从头构建自定义 UI 组件最干净的工具之一。
常见问题
不会。all 属性不会影响 CSS 自定义属性、direction 或 unicode-bidi。你的 --color-primary 或其他自定义变量将原封不动地传递,这在构建从父级作用域继承设计令牌的主题化组件时非常有用。
因为 all: unset 会将属性重置为 CSS 规范默认值,而不是浏览器默认值。按钮会失去其 inline-block 显示、内边距、边框和光标。你需要在重置后手动恢复这些属性,包括 display、cursor、box-sizing,以及为键盘用户设置的 focus-visible 轮廓。
当从头构建一个没有浏览器样式的自定义组件时,使用 all: unset。当你想撤销自己的样式表规则但保留浏览器的用户代理默认值时,使用 all: revert。对于大多数自定义按钮和表单控件,unset 是更好的选择。
可以。all 属性在所有现代浏览器中都有强大的支持,包括 Chrome、Firefox、Safari 和 Edge。它已经稳定多年。主要风险不是浏览器兼容性,而是意外重置你想保留的属性,特别是焦点样式和对布局至关重要的 display 值。
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..