CSS变量无法自动跨iframe同步,因其作用域严格绑定各自document;同源需监听load后动态注入<style>或setProperty,跨域唯一可靠方式是postMessage通信并校验origin后手动设置变量。

CSS变量本身不能解决iframe内外部主题同步问题,它只是状态载体;真正起作用的是通信机制和变量注入时机。
同源 iframe 中必须用 JS 注入 :root 变量
父页改 document.documentElement.style.setProperty('--theme-color', 'blue'),子 iframe 完全无感——因为变量作用域绑定各自 document。你得主动把变量写进 iframe 的 :root 里。
- 监听
iframe.onload,确保contentDocument可访问(早于 load 会得null) - 不要用
@import或克隆<link>标签:它们加载的 CSS 仍查自己的:root,而那里没定义变量 - 推荐方式:动态创建
<style>插入iframe.contentDocument.head,内容为:root { --primary: #007bff; } - 若 iframe 页面已含
:root,也可直接调iframe.contentDocument.documentElement.style.setProperty()
跨域 iframe 唯一可靠路径是 postMessage
跨域时 contentDocument 被浏览器拦截,Blocked a frame from accessing a cross-origin frame 是常态。此时不能传样式,只能传值。
- 父页发送:
iframe.contentWindow.postMessage({ type: 'SET_THEME', vars: { '--primary': '#007bff' } }, 'https://target-domain.com') - 子页监听
message事件,严格校验e.origin(禁用'*'),再遍历vars调用document.documentElement.style.setProperty(key, value) - 别往
document.body.style上设变量——它不参与级联,var(--x)查不到 - Safari 默认禁用
BroadcastChannel,且它不跨应用(只限同 origin tab),别踩这个坑
localStorage 同步只适用于同二级域名场景
如果所有应用部署在 ui.example.com/app1 和 ui.example.com/app2 这类相同二级域名下,localStorage 才能共享。
立即学习“前端免费学习笔记(深入)”;
- 父页切换主题时执行:
localStorage.setItem('theme', 'dark') - 每个应用在
DOMContentLoaded时读取并设置:document.documentElement.setAttribute('data-theme', value) - 注意竞态:若 iframe 加载快于父页写入
localStorage,初始主题就会错;服务端注入<html data-theme="dark">更稳 - 不同域名(如
app1.example.com和app2.example.com)之间localStorage完全隔离,无效
最容易被忽略的一点是:CSS 变量不是“活”的——父页改了变量,iframe 内不会自动响应;它不依赖嵌套关系,只认自己 document 里的声明。所谓同步,本质是你在外部触发动作后,手动让每个应用重新执行一次变量设置逻辑。


















