shadow dom 不继承外部 :root 的 css 变量,需通过 :host 或 ::slotted 显式透传主题变量,并配合 data-theme 属性、color-scheme 声明及变量绑定实现深色模式适配。

Shadow DOM 内部不会自动继承外部 :root 的 CSS 变量,所以直接在主文档 :root 里定义的 --bg-color、--text-color 等变量,在 Shadow DOM 里是读不到的。想让它响应深色模式,必须显式把变量“透传”进去。
在 :host 或 ::slotted 中手动声明变量
最稳妥的做法是在组件的 Shadow Root 样式中,用 :host 或 ::slotted 选择器重新声明变量,并与外部主题状态联动:
:host([data-theme="dark"]) { --bg-primary: #121212; --text-primary: #e0e0e0; }-
:host(:not([data-theme])) { --bg-primary: #ffffff; --text-primary: #1a1a1a; }(兼容无 data-theme 的情况) - 如果组件内容通过
<slot></slot>插入,可用::slotted(*)控制插槽内元素的基础颜色
用 CSS 自定义属性 + 属性绑定透传主题
不要让 Shadow DOM “猜”主题,而是由外部明确传入:
- 主页面设置
<my-card data-theme="dark"></my-card> - 组件内部用
:host([data-theme="dark"])匹配,并覆盖变量值 - 也可配合 JS 在
connectedCallback中读取this.getAttribute('data-theme'),再动态设置this.shadowRoot.host.style.setProperty()(仅限必要场景)
避免只靠 matchMedia 或 class 切换
Shadow DOM 是样式隔离的,document.documentElement.classList.add('dark') 对它完全无效:
- 不能指望外部
.dark类自动影响 Shadow 内部样式 - 也不能直接监听
window.matchMedia('(prefers-color-scheme: dark)')后只改外部:root—— 这个变化不会穿透 Shadow Boundary - 必须在 Shadow Root 内部单独注册监听,并同步更新自己的
:host变量或 class
确保原生控件也适配
Shadow DOM 里的 <input>、<select></select> 等默认控件,在深色系统下仍可能显示亮色背景:
- 给
:host添加color-scheme: light dark,让浏览器知道该组件支持双模式 - 必要时对
input、textarea等单独重置background-color和color,但优先依赖系统自动适配 - 避免硬写
background: #000—— 应始终基于变量,如background-color: var(--bg-primary);











