Shadow DOM 默认隔离样式,但 slot 分发的内容仍属 Light DOM,外部样式可作用于其节点;::slotted() 是唯一能样式化分发内容的伪类,仅匹配顶层节点且不支持伪类;需用内联样式、::slotted(*) 重置或 named slot + ::slotted([slot="name"]) 精准控制。

Shadow DOM 默认会隔离样式,外部 CSS 无法穿透作用到 Shadow 树内部节点,包括 <slot></slot> 中分发进去的内容(即“分发节点”)。但这个隔离不是绝对的,实际行为取决于插槽内容的归属和继承规则。
插槽内容的样式归属决定是否受外部影响
<slot></slot> 本身不渲染,它只是内容的“出口”。真正被插入的是来自 Light DOM 的节点。这些节点仍属于原始 Light DOM 树,其样式计算依然遵循原有作用域:
- 如果外部样式选择器匹配了这些节点(比如
button { color: red; }),且没有被 Shadow 内部更具体的选择器覆盖,样式依然生效 - 它们不会继承 Shadow 主机元素的 CSS 自定义属性(除非显式设置
inherit或使用::slotted()透传) - 普通类名、标签名、属性选择器在 Light DOM 中有效,不受 Shadow 边界阻挡
::slotted() 是唯一能直接样式化分发内容的伪类
::slotted() 允许你在 Shadow 样式中针对被 <slot></slot> 分发进来的节点声明样式,但它有明确限制:
- 只匹配顶层分发节点(不能写
::slotted(div span),只能::slotted(span)) - 不支持伪元素或伪类(如
::slotted(:hover)无效) - 可结合属性选择器(
::slotted([slot="icon"]))和自定义属性(--color)增强控制 - 它的优先级通常低于 Light DOM 中同级选择器,必要时可用
!important(但应谨慎)
避免意外样式污染的实用建议
若希望插槽内容完全“听从 Shadow 内部规则”,需主动干预:
- 在组件 Light DOM 使用内联样式或
style属性锁定关键样式(如<button style="font-size: var(--btn-size, 14px)"></button>) - Shadow 样式中用
::slotted(*)重置通用属性(如all: initial;),再逐个设置所需样式 - 对需要强隔离的场景,改用
slot="name"+named slot结构,配合::slotted([slot="name"])精准控制 - 避免依赖外部全局类名;推荐通过
part属性 +::part()(而非::slotted)暴露可定制子部分
Shadow DOM 的样式边界是“节点归属”和“选择器作用域”的组合结果,插槽内容天然保留在 Light DOM 上下文里。理解这一点,就能预判哪些外部样式会生效、哪些必须由 Shadow 主动接管。


















