css变量必须显式声明在宿主元素上才能被shadow dom读取,查找链在宿主处终止,:root、body或父容器声明均无效;验证方式为getcomputedstyle(host).getpropertyvalue('--x')是否为空。

变量根本没挂到宿主元素上
浏览器查找 var(--x) 时,只沿 DOM 树向上找最近一个**显式声明了 --x 的祖先元素**,且这个查找在宿主元素(如 <my-button></my-button>)处就终止——:root、body、父容器 <div class="theme"> 全都不在链上。
<p>常见错误包括:</p>
<ul>
<li>在 <code>:root 或 body 中写 --color: red;,以为全局生效
.wrapper > my-button { --color: red; } —— 变量没落在 my-button 自身,继承链直接断裂class="dark",但没配 CSS 规则把变量挂到宿主标签上验证方式很简单:getComputedStyle(host).getPropertyValue('--color') 返回空字符串,就说明变量压根没挂上去。
:host 转发时用了 fallback 导致递归卡死
:host 是唯一能“接住”外部变量并向下透传的入口,但它本身不自动继承。你得写 :host { --bg: var(--bg); } 来中转——但这里极易踩坑:
- ❌
:host { --bg: var(--bg, #fff); }:fallback 会触发无限递归,Chrome/Firefox 可能卡死或静默失败 - ❌
:host { all: initial; }或all: unset;:清空所有继承属性,包括 CSS 变量,var()直接回退 fallback 且无任何提示 - ✅ 正确做法是
:host { --bg: var(--bg); }(无 fallback),再在子元素里用background-color: var(--bg, #fff);
注意::host 规则必须写在 shadow 内部的 <style></style> 中,外部 CSS 文件里写 my-button:host 完全无效。
iOS Safari 16.4 之前存在 WebKit 级别 bug
哪怕写法完全正确,在 iOS Safari 16.4 之前的版本里,var(--x) 仍可能返回 undefined。这不是代码问题,而是 WebKit 引擎缺陷:变量已挂在宿主上,但 shadow 内部读不到。
检测方式:
- 运行
getComputedStyle(document.createElement('div')).getPropertyValue('--test')看是否为空 - 结合
window.CSS判断是否支持原生变量 - 若需兼容,得降级为 JS 设置
element.style.color,或用adoptedStyleSheets配合内联变量声明
这个 bug 不报错、不警告,DevTools 里也看不出异常,最容易被当成“自己写错了”反复排查。
漏写 fallback 让样式静默失效
所有 var() 必须带 fallback,否则变量未定义时,整个 CSS 声明会被丢弃:
-
color: var(--text-color);→ 若--text-color未定义,color变成inherit,最终计算为黑色(a 标签甚至还是 UA 蓝色) -
background-color: var(--bg-color);→ 回退为transparent,不是白色 - ✅ 正确写法:
color: var(--text-color, #333);、background-color: var(--card-bg, #ffffff);
拼错变量名(如 --Text-Color vs --text-color)同样导致 fallback 生效,但控制台不会报错,Computed 面板只显示 invalid —— 调试时得右键 Shadow 内节点 → “Show inherited CSS properties”,看变量是否真出现在继承链里。
var() 漏掉 fallback、变量没声明在宿主元素上——任一出问题,主题就会在某个组件里静默失效,控制台不会报错,DevTools 里也看不出异常。











