通配符选择器*会直接拖慢首次渲染、干扰第三方组件、增加调试难度,因其强制全量遍历所有dom节点(含script、meta、注释等),无索引可依,导致recalculate style时间飙升,500+节点时易超20ms,引发卡顿与首屏延迟。

通配符选择器 * 在大型项目中不是“能用就行”,而是会直接拖慢首次渲染、干扰第三方组件、让调试变成猜谜游戏——它匹配所有节点,包括 <script></script>、<meta>、注释,浏览器必须逐个检查,没法跳过。
为什么 * 会让 Recalculate Style 时间飙升
浏览器匹配 CSS 是从右往左的,* 没有索引、无法剪枝,只能全量遍历 DOM。哪怕只写了一条 * { box-sizing: border-box; },DOM 节点超过 500 个时,样式计算就容易突破 20ms,滚动卡顿、首屏延迟立马出现。
-
*::before或*::after更糟:一个元素 → 生成两个伪节点 → 实际匹配目标翻倍甚至更多 - 它阻断继承判断:比如
html { font-size: 16px; }本可被子元素自然继承,但* { font-size: 14px; }会强制重算每个节点 - 后续同级选择器也会变慢:浏览器必须确认没被
*覆盖,无法复用样式缓存
* 看似清样式,实则埋冲突
* { margin: 0; padding: 0; } 不是“重置”,是用最低特异性规则强行覆盖一切,结果就是:表单控件失去点击区域、<select></select> 高度塌缩、SVG 图标被压缩、屏幕阅读器布局断裂。
- 第三方组件(如
react-datepicker)依赖默认margin布局,*一加,日历弹窗立刻错位 -
* { user-select: none; }会禁用所有文本选中,连<textarea></textarea>和代码块都不可复制 - 继承权重是 NULL,
* { color: green; }会压过div { color: red; }下的<span></span>继承色
真正该用什么替代 *
现代项目里,“少用 *”不是妥协,而是换更可控的写法。关键不是删掉那几行,而是把“全局意图”落到有索引、可审计的位置。
- 盒模型统一:改用
html { box-sizing: border-box; }+*::before, *::after { box-sizing: inherit; }(这是唯一合理保留*的地方) - 边距重置:显式列举白名单,如
body, h1, h2, p, ul, ol, form, button { margin: 0; padding: 0; } - 局部重置:用
all: unset,例如.card > * { all: unset; }(注意 IE 不支持,iOS Safari 15.4+ 才稳定) - 降权不降效:用
:where(*)替代,它不增加特异性,且 Chrome/Firefox 对其做了匹配路径优化
怎么查你项目里有没有隐性 * 陷阱
很多性能问题不是你写的 *,而是框架或 UI 库悄悄注入的。光看自己写的 CSS 不够,得看运行时最终生效的样式表。
- DevTools → Elements → 右键任意元素 → “Inspect styles”,搜索
*(勾选 “Show all”) - Coverage 面板(Cmd+Shift+P → “Coverage”)reload 页面,看哪些含
*的规则被解析却“未使用” - 构建产物里搜
"*",尤其注意node_modules下的 reset.css、normalize.css 是否含* - 运行
getComputedStyle(document.body).boxSizing,如果不是border-box,说明重置没生效,可能被其他*干扰了
最难察觉的不是 * 写在哪,而是它让 Layout 时间从 3ms 涨到 18ms 时,你在 DevTools 里根本看不到警告——它安静地藏在 Recalculate Style 的长尾里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











