Shadow DOM 是 Web Components 的核心技术,提供独立 DOM 环境实现样式、结构和行为的封装;通过 attachShadow 创建影子树,挂载到宿主元素上,支持 open(可访问)和 closed(不可访问)模式;其核心优势为样式隔离,内部 CSS 不影响外部,外部样式默认不穿透,可通过 CSS 变量传递主题;利用 slot 可实现 Light DOM 内容投影,支持具名插槽进行布局分发;尽管 closed 模式可增强封装,但仍存在绕过风险,主要用于逻辑隔离;整体上 Shadow DOM 有效避免全局污染,提升组件复用性与健壮性,适用于构建 UI 库和设计系统。

Shadow DOM 是 Web Components 的核心技术之一,它为组件提供了一个独立的 DOM 环境,实现真正的封装——包括样式、结构和行为。使用 Shadow DOM 可以避免全局样式污染,防止外部 JavaScript 意外修改组件内部结构,让前端组件更健壮、可复用。
什么是 Shadow DOM
Shadow DOM 允许开发者将一个隐藏的、独立的 DOM 树附加到某个元素上,这个“影子树”与主文档 DOM 隔离,有自己的作用域。
每个 Shadow Root 都挂载在一个宿主元素(Host)上,外部无法直接访问其内部结构,样式也不会泄露出去,实现了良好的封装性。
例如:
立即学习“Java免费学习笔记(深入)”;
const host = document.createElement('div');
const shadowRoot = host.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = '<span>这是影子DOM中的内容</span>';
document.body.appendChild(host);
这段代码创建了一个带有 Shadow DOM 的 div,其中的内容不会被外部 CSS 影响,除非特别设置穿透规则。
封闭模式:open 与 closed
创建 Shadow Root 时可以通过 mode 参数控制访问权限:
- open:可通过 JavaScript 在外部访问 Shadow Root,如 element.shadowRoot
- closed:Shadow Root 不可从外部访问,增强了封装性
示例:
const shadowRoot = host.attachShadow({ mode: 'closed' });
// 外部调用 host.shadowRoot 将返回 null
虽然 closed 模式看似更安全,但目前仍可通过一些手段绕过(如重写 attachShadow 方法),因此更多用于逻辑隔离而非绝对安全防护。

专业的AI封面生成工具,支持小红书、公众号、小说、红包、视频封面等多种类型,一键生成高质量封面图片。
108
查看详情
样式隔离与作用域CSS
Shadow DOM 最大的优势之一是样式隔离。在 Shadow Root 中定义的 CSS 不会影响外部页面,外部样式也默认不作用于内部元素(除非使用继承属性)。
可以在 Shadow Root 内部直接写 style 标签:
shadowRoot.innerHTML = `
<style>
span { color: blue; font-size: 16px; }
</style>
<span>蓝色文本</span>
`;
如果希望某些样式能被继承(如字体、颜色等),可以结合 CSS 自定义属性(变量)实现灵活的主题传递:
:host {
--text-color: #333;
}
span {
color: var(--text-color);
}
与 Light DOM 的交互
主文档中的元素称为 Light DOM,它们可以被投影(slot)进 Shadow DOM,实现内容分发。
使用 <slot> 标签可以插入外部内容:
// 宿主元素包含原始内容 host.innerHTML = '<b>加粗文字</b>'; // Shadow DOM 中定义插槽 shadowRoot.innerHTML = '<slot></slot>';
渲染后,<b>加粗文字</b> 会被插入到 slot 位置,但仍受 Shadow DOM 样式限制。
还可以使用具名 slot 实现复杂布局:
shadowRoot.innerHTML = ` <header><slot name="title"></slot></header> <main><slot>默认内容</slot></main> `;
基本上就这些。Shadow DOM 提供了强大的封装能力,是构建可复用、高内聚组件的关键技术,尤其适合开发设计系统或 UI 库。
大家都在看:
在css中如何用color关键字定义颜色
如何用HTML插入进度指示器_HTML CSS自定义进度条动画实现
如何用css link和media属性控制加载
css animation-delay对多个子元素如何应用

































暂无评论内容