css变量不跨iframe传递,需同源时手动注入或跨域时用postmessage同步;调试应检查devtools中“defined in”来源是否为子页面documentelement。

iframe 有独立的 document,CSS 变量不跨文档传递
CSS 变量(--my-var)只在定义它的 document 内生效,父页面设置 document.documentElement.style.setProperty('--color', 'red'),对子 iframe 的 documentElement 完全无效——它俩是两个隔离的 DOM 树和样式作用域。
同源时也不能“自动继承”,必须手动注入到子 document
即使 iframe 和父页同源,变量也不会透传。常见错误是以为设了父级 :root 就够了,其实子页面得自己声明或接收:
- 监听
load事件,确保iframe.contentDocument可访问(提前访问会是null) - 用
createElement('style')+textContent向子head插入规则,例如::root { --primary: #007bff; } - 避免用
innerHTML,防止 XSS;也不要直接复用父页的<link>或<style></style>节点(会报insertBefore错误) - 若子页面已有
:root,可用iframe.contentDocument.documentElement.style.setProperty()动态更新
跨域时唯一可行路径是 postMessage + 手动应用
跨域下 contentDocument 不可读,postMessage 是标准解法,但容易漏掉关键环节:
- 父页发送时必须指定目标 origin(不能用
'*'),例如:iframe.contentWindow.postMessage({ type: 'SET_VARS', vars: { '--primary': '#007bff' } }, 'https://child.example.com') - 子页收到后,必须校验
e.origin,再遍历vars对象,逐个调用document.documentElement.style.setProperty(key, value) - 子页 CSS 中必须实际用到
var(--primary),否则变量设了也无视觉效果 - 如果子页用了
all: unset或all: initial,会清空所有自定义属性,导致var()回退 fallback
调试时最该盯住的不是语法,而是“Defined in”位置
DevTools 的 Computed 面板里搜目标变量,点开箭头看 “Defined in” —— 如果显示 inherited from ,说明中间某层根本没声明;如果显示 not set 或来源是其他第三方样式表,大概率是被覆盖或未加载。
最容易被忽略的是:变量是否真的出现在子页面的 documentElement.style 里,而不是只存在于父页 JS 对象或控制台临时赋值中。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











