<p>* { margin: 0; padding: 0; box-sizing: border-box; } 是唯一勉强可接受的通配符写法,因其能收敛跨浏览器块级元素空白差异并统一盒模型计算,但必须置于CSS最顶部且不可加父选择器或!important。</p>

别用 * 做全局重置,除非你只写三行且放最顶上。 它看起来省事,但实际会拖慢渲染、破坏表单可访问性、让伪元素行为异常,而且多数所谓“重置”根本不是必需的。
为什么 * { margin: 0; padding: 0; } 是唯一勉强能接受的写法
浏览器对 h1、fieldset、ul 等元素的默认 margin 和 padding 差异大,跨浏览器不一致;box-sizing: border-box 则让宽度计算更可控。这三项是仅有的、既解决实际兼容问题又不明显破坏语义的声明。
-
margin: 0和padding: 0能收敛多数块级元素的空白差异 -
box-sizing: border-box必须配,否则后续width: 100%在深层嵌套中极易溢出 - 加
font-family、color、background会污染继承链,比如让button变成不可读的黑底白字 -
*::before, *::after { box-sizing: border-box }是冗余的——伪元素不继承该属性,还强制重绘所有伪节点
* 必须放在 CSS 文件最顶部,且不能加父选择器
* 的特异性是 (0,0,0,0),它只有在没有任何更高权重规则先于它时才真正生效。顺序错了,等于没写。
- ✅ 正确:
*块必须是整个样式表的第一个规则 - ❌ 错误:
.container *或body *—— 这已不是通配符选择器,而是后代选择器,性能更差(需遍历所有后代) - ⚠️ 预处理器陷阱:Sass 中
* { @extend %reset; }会打乱特异性计算,应避免 - 别加
!important:它会让.debug-border这类调试类完全失效,掩盖真实冲突
真正需要“归零”时,优先用 all: unset 或 revert
比起无差别匹配全 DOM,all: unset 更精准:它只重置当前元素自身所有 CSS 属性为初始值或继承值,不递归影响子元素,也不触发全局匹配开销。
立即学习“前端免费学习笔记(深入)”;
-
.card > * { all: unset; }安全作用于卡片直系子元素,不影响伪元素和 Web Component 内部 - 对表单控件要“放行”:
input, select, textarea, button { all: revert; }——revert会退回浏览器默认样式,而不是留白 -
:where(html, body, h1, p, ul) { margin: 0; }是更轻量的替代写法,特异性为 0,不会干扰后续规则
哪些场景下 * 反而可以放心用
它不是不能用,只是不该出现在生产 CSS 的顶层作用域里。
- DevTools 临时调试:
* { outline: 1px solid red !important; }查布局边界很高效,但上线前必须删掉 - Shadow DOM 隔离环境:
::host * { box-sizing: border-box; }是安全的,作用域天然受限,不穿透宿主文档 - 绝对不要在 JS 动态注入样式时用
document.styleSheets[0].insertRule('* { ... }', 0)—— 顺序难控,易被覆盖
最容易被忽略的点是:哪怕你写了 *,只要它不在 CSS 文件最顶部,它的 margin 和 padding 就大概率被后面更高特异性的规则覆盖——顺序比写法更重要。


















