子组合器在 Shadow DOM 中完全不生效,因为浏览器在样式计算阶段就用 shadow boundary 拦截外部 CSS 规则,div > button 等选择器根本不会匹配 shadowRoot 内部节点。

为什么 > 子组合器在 Shadow DOM 里完全不生效
因为浏览器压根不会拿外部 CSS 规则去匹配 Shadow DOM 内部节点——> 是选择器的一部分,而整个选择器在样式计算阶段就被边界拦下了,连“尝试匹配”这一步都不会发生。
div > button 匹配不到 shadowRoot 里的 button
常见错误现象:你在页面上写 div > button { color: red; },但自定义组件 <my-button> 内部的 <button> 依然黑色。这不是权重低或漏写了 !important,是这条规则根本没参与它的样式计算。
- Shadow DOM 的样式边界在 CSSOM 构建时就起效,外部
<style>或<link>中的所有规则,包括含>、+、~、空格后代等组合器的,全部被跳过 -
>要求父元素必须是直接父级,而宿主元素(如<my-button>)和 shadowRoot 内部的<button>不在同一树层——中间隔着 shadow boundary,浏览器不认为它们构成“父子”关系 - 即使你把选择器写成
my-button > button,它也只匹配 light DOM 中直接子<button>(即插槽外的内容),对 shadowRoot 里的任何节点都无效
想控制 shadow 内部结构,只能靠 :host 和 ::slotted()
W3C 只允许这两个伪类跨 boundary,且作用严格受限:
-
:host > button是合法的,但它匹配的是宿主元素自身(<my-button>)的直接子元素——仅当那个<button>在 light DOM 里、且被<slot>投影进来时才生效 -
::slotted(button)可以选中插槽分发进来的<button>,但仅支持可继承属性(color、font-family等),margin、display、width全部忽略 - 想真正控制 shadow 内部布局?必须把样式注入到
shadowRoot里,例如用document.createElement('style')创建后shadowRoot.appendChild(style)
容易被忽略的关键点
很多人调试时看到 DevTools 里能展开 shadowRoot、能看到内部 DOM 节点,就误以为“样式应该能生效”。其实这只是 DOM 渲染可见,不代表样式引擎把它纳入了匹配候选集——computed 样式面板里如果没出现对应规则,基本可以断定:选择器连 CSSOM 都没进去。
立即学习“前端免费学习笔记(深入)”;


















