星号选择器不匹配伪元素、注释节点、文本节点、document根节点、SVG非渲染节点及iframe内元素;在Shadow DOM中需:host 或::slotted(*);影响性能且难维护,应限定范围或显式列举元素。

星号选择器 * 真的会匹配“所有元素”吗?
不会。它只匹配「文档树中所有非伪元素的节点」,不包括 ::before、::after、::placeholder 这类伪元素,也不匹配注释节点、文本节点或文档根节点(document 本身)。实际开发中,它常被误认为能重置一切样式,但连 和 都要显式写进去才生效。<ul>
<li>
<code>* 不匹配 SVG 元素内部的 <defs></defs>、<style></style> 等非渲染节点
:host * 或 ::slotted(*) 才能作用于插槽内容<iframe></iframe>,* 对子 iframe 内容完全无效用 * 做全局 box-sizing 更安全的写法
很多人直接写 * { box-sizing: border-box; },看似省事,但会意外影响 SVG 的 <svg></svg>、<foreignobject></foreignobject> 甚至某些 UI 库的 canvas 容器——它们依赖 content-box 计算尺寸。更稳妥的做法是限定范围。
- 优先用
*, *::before, *::after { box-sizing: border-box; }—— 补上伪元素,避免伪元素仍按content-box渲染导致布局错位 - 对 SVG 场景,加例外:
svg *, svg *::before, svg *::after { box-sizing: content-box; } - 若项目用 Web Components,建议改用
:host * { box-sizing: border-box; },避免污染全局
* 的性能代价比你想象中大
浏览器解析 * 时,会为每个新挂载的元素(包括动态插入的)做一次全量匹配检查。在长列表、高频 DOM 操作或低端设备上,可能触发强制同步布局(Layout Thrashing)。这不是理论风险,真实监控中见过 * 导致滚动掉帧。
- Chrome DevTools 的 “Rendering” 面板开启“Paint Flashing”,滚动时大片闪烁基本就是
*在反复重绘 - Webpack 构建时若用 css-loader + postcss-preset-env,
*无法被安全地 scope 化或 tree-shake - 替代方案:用
html, body, div, p, span, section, article, header, footer, nav, aside, main显式列举常用容器/文本元素,性能提升明显且覆盖率达 95%+
为什么 * + * 和 * > * 很少真正有用
这两个组合看起来强大,实则极易失控。* + * 会命中所有相邻兄弟关系(比如 <p></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板"><img
src="https://img.php.cn/upload/webcode/000/000/018/178607072210981.jpg" alt="CSS婚礼策划服务机构宣传网站模板" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="overflowclass">CSS婚礼策划服务机构宣传网站模板</a>
<p class="overflowclass">CSS婚礼策划服务机构宣传网站模板是一款适合提供婚礼策划和婚庆服务机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。</p>
</div>
<a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<div></div>),但现代框架生成的 DOM 常含大量空文本节点或注释,导致选择器行为不可预测;* > * 则几乎等价于 body > *,因为只有顶层元素才满足“父元素是任意元素”的条件——而这个“任意父元素”大概率就是 或 <shadow-root></shadow-root>。
-
* + *在 Vue/React 组件中会错误匹配组件边界处的换行符生成的文本节点,导致样式错乱 -
* > *实际效果接近body > *, html > *,但更难调试、更难覆盖 - 真需要相邻样式,直接用语义化类名,比如
.section + .section { margin-top: 2rem; },稳定且可维护
最麻烦的不是语法,是它看起来太简单,结果让人忽略层级、Shadow DOM、动态插入和伪元素这些真实存在的边界条件。写之前先问一句:这个“所有”,到底是哪个上下文里的所有?
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










