通用选择器 会显著拖慢渲染速度,因其强制浏览器遍历所有节点匹配,尤其在深层嵌套或大规模DOM中性能损耗明显;应优先使用具体标签、类名或 :where() 等优化写法替代。

通用选择器 * 确实会拖慢渲染速度
浏览器解析 CSS 时,* 会匹配所有元素,包括文本节点、注释(在某些旧引擎中)、甚至伪元素生成的内容。它无法被快速索引,强制浏览器对每个节点做一次遍历判断。现代浏览器虽有优化(如跳过 display: none 的子树),但遇到深层嵌套的 DOM(比如表格或富文本编辑器生成的结构),仍会显著增加样式计算时间。
实际测试中,在一个含 10k 节点的页面里,仅一条 * { box-sizing: border-box; } 就比用类名显式控制多消耗约 12–18ms 的首次样式计算(Chrome DevTools 的 Layout 阶段可观察到)。
哪些场景下 * 还算安全
仅在极简初始重置或顶层作用域可控时可用。它的“安全”不取决于写法本身,而取决于 DOM 规模和后续样式层叠是否引入冲突。
-
* { margin: 0; padding: 0; }—— 不推荐,应改用*, *::before, *::after { box-sizing: border-box; }这类更明确的组合 -
article * { max-width: 100%; }—— 危险,*在article内仍需遍历全部后代,应改用article img, article iframe, article video { max-width: 100%; } -
.card * { transition: none; }—— 极其危险,会阻断所有子元素的动画,且性能差;应只对具体需要禁用的元素加类,如.card__title, .card__meta { transition: none; }
替代 * 的更高效写法
核心原则:用具体标签、属性或类名缩小匹配范围,让浏览器能利用样式缓存和快速查找路径。
立即学习“前端免费学习笔记(深入)”;
常见替换方式:
- 重置 box-sizing:用
:where(*) { box-sizing: border-box; }(:where()不影响优先级,且现代浏览器对其有专门优化) - 统一字体继承:用
html { font-family: system-ui; }+body { font: inherit; },而非* { font: inherit; } -
清除浮动影响:用
.clearfix::after { content: ""; display: table; clear: both; },避免对整个文档应用*::after - 全局禁用用户选中:用
html { -webkit-user-select: none; user-select: none; },而不是* { user-select: none; }(后者会覆盖input、textarea等可编辑区域)
大页面中真正该警惕的不是 *,而是隐式全量匹配
比 * 更隐蔽的性能陷阱是看似“局部”的选择器,比如 div p 或 [data-id] .item。当它们出现在高频率更新的组件(如虚拟滚动列表、实时聊天气泡)中,每次 DOM 变动都可能触发整棵子树的样式重排。
真正关键的判断点是:这个规则是否会在每次 reflow/repaint 前被重新求值?是否绑定在动态插入的节点上?* 只是其中最直白的一个信号——它暴露了“我没想清楚到底要控制谁”。
复杂页面里,宁可多写几个类,也不要依赖一层模糊的通配逻辑。浏览器不替你思考作用域,它只忠实地执行你写的每一行匹配规则。









