无需登录 数据私有 本地保存

CSS 作用域演示 - Shadow DOM 样式隔离效果

102
0
0
0

核心术语与知识库

CSS 作用域(CSS Scoping)

CSS 作用域是指 CSS 规则的作用范围或生效边界。在传统 CSS 中,所有样式规则都作用于全局命名空间,任何样式表中定义的规则都可能影响页面上的任何元素。CSS 作用域的目标是限制样式规则的影响范围,使其只作用于特定的元素集合。实现 CSS 作用域的方式包括 CSS Modules、CSS-in-JS 库、Shadow DOM 以及新兴的 CSS @scope 规则等。

Shadow DOM

Shadow DOM 是 Web Components 规范中的核心 API 之一,它允许开发者在 HTML 元素下附加一棵隔离的 DOM 子树(Shadow Tree)。Shadow Tree 拥有自己独立的 DOM 结构和样式规则,与宿主元素所在的主文档 DOM 树相互隔离。Shadow Tree 中定义的样式不会影响外部元素,外部样式也不会影响 Shadow Tree 内部的元素。这种双向隔离机制是实现 CSS 样式隔离的根本解决方案。

Shadow Root

Shadow Root 是 Shadow Tree 的根节点,是通过 Element.attachShadow() 方法创建的。每个宿主元素最多只能有一个 Shadow Root。Shadow Root 是 Shadow Tree 的入口点,所有属于 Shadow Tree 的 DOM 节点都是 Shadow Root 的后代。Shadow Root 分为 open 和 closed 两种模式,open 模式允许外部通过 element.shadowRoot 属性访问 Shadow Root,closed 模式则禁止外部访问。

Shadow Tree

Shadow Tree 是附加在宿主元素上的隔离 DOM 子树。它以 Shadow Root 为根节点,包含完整的 DOM 结构和关联的样式。Shadow Tree 中的元素只能通过 Shadow Root 访问,外部的 querySelector 等方法无法直接选取 Shadow Tree 内部的元素。Shadow Tree 的存在使得组件的内部 DOM 结构对外部完全透明。

CSS 自定义属性(CSS Custom Properties)

CSS 自定义属性,也称为 CSS 变量,是 CSS3 引入的允许开发者定义可重用值的特性。使用 -- 前缀定义变量,通过 var() 函数引用变量值。CSS 自定义属性的重要特性是它们可以穿透 Shadow DOM 边界,这使得它们成为在 Web Components 架构中实现主题定制和组件通信的关键机制。

:host 选择器

:host 是 Shadow DOM 中的一个特殊伪类选择器,用于选择包含 Shadow Tree 的宿主元素。:host 选择器只能在 Shadow Tree 的样式表中使用,它是 Shadow DOM 中唯一能从 Shadow Tree 内部影响外部宿主元素样式的选择器。:host 可以与伪类组合使用,如 :host(:hover) 用于定义宿主元素被悬停时的样式。

:host-context() 选择器

:host-context() 是另一个与宿主元素相关的伪类选择器。它选择匹配参数选择器的宿主元素的上下文中包含的宿主元素本身。例如 :host-context(.dark-theme) 表示当宿主元素位于具有 dark-theme 类的祖先元素内部时应用样式。这个选择器在实现主题适配时非常有用。

样式泄漏(Style Leakage)

样式泄漏是指组件或模块中定义的 CSS 规则意外影响了其他组件或模块的样式表现。样式泄漏是传统全局 CSS 架构中最常见的问题之一,它导致了组件之间的紧耦合和不可预测的样式行为。当项目规模增大、组件数量增多时,样式泄漏的问题会变得更加严重。Shadow DOM 通过样式隔离机制从根本上防止了样式泄漏。

Web Components

Web Components 是一组 W3C 标准 API,允许开发者创建可重用的自定义 HTML 元素。Web Components 由三项核心技术组成:Custom Elements(自定义元素)、Shadow DOM(影子文档对象模型)和 HTML Templates(HTML 模板)。Web Components 目标是在不依赖任何前端框架的情况下提供组件化的开发能力,创建的组件可以在任何支持 Web 标准的环境中使用。

Custom Elements(自定义元素)

Custom Elements 是 Web Components 规范中用于定义和注册自定义 HTML 元素的 API。通过 CustomElementRegistry.define() 方法,开发者可以将一个类注册为自定义元素。注册后的自定义元素可以像标准 HTML 元素一样在文档中使用。Custom Elements 提供了生命周期回调函数,如 connectedCallback、disconnectedCallback 等,用于管理元素的创建、挂载和销毁行为。

::part() 伪元素

::part() 是 Shadow DOM 中用于从外部选择 Shadow Tree 内部标记为 part 的元素的伪元素选择器。宿主元素的使用者可以通过 ::part(partname) 语法选择和样式化 Shadow Tree 中具有对应 part 属性的元素。这是在保持样式隔离的同时允许有限外部样式定制的机制。

open 与 closed 模式

Shadow Root 的两种创建模式。open 模式(attachShadow({ mode: 'open' }))允许外部代码通过 element.shadowRoot 属性获取 Shadow Root 的引用。closed 模式(attachShadow({ mode: 'closed' })则不暴露 Shadow Root 引用,外部代码无法通过常规方式访问 Shadow Tree 内部。closed 模式提供了更强的封装性,但也会限制调试和某些框架的集成能力。

CSS @scope 规则

CSS @scope 是一项新的 CSS 规范提案,旨在原生支持 CSS 作用域。@scope 规则允许开发者定义样式规则的作用范围,使其只影响指定选择器范围内的元素。与 Shadow DOM 不同,@scope 不创建 DOM 隔离,仅在 CSS 层面限制样式的作用范围。目前 @scope 规则在主流浏览器中的支持仍在推进中。