Safari 并非不支持 CSS 变量,而是对变量可见性、作用域和计算时机要求极严:JS 动态设置的变量在 getComputedStyle() 中返回空字符串,@supports 检测失败,@keyframes 中静默丢弃规则,均因其未完成样式计算或未被 CSSOM 扫描到;必须强制重排(如 el.offsetHeight)后读取,且变量定义位置与查询目标需严格匹配,伪元素需兜底,低版本(iOS 12–14)甚至语法级忽略 var(),后备值无效,降级需前置 fallback 并依赖静态定义。

不是 Safari “不支持 CSS 变量”,而是它对变量的可见性、作用域和计算时机要求极严——JS 动态设置的变量在 getComputedStyle() 里返回空字符串、@supports (color: var(--x)) 检测失败、@keyframes 里直接静默丢弃整条规则,都是因为它根本没“看到”或“认可”那个变量值。
getComputedStyle().getPropertyValue('--x') 在 Safari 中返回空字符串
这不是读取失败,是 Safari 拒绝在样式未完成计算时暴露变量值。哪怕只早执行 1ms,结果就是 ""。
- 必须确保调用前触发强制重排:
el.offsetHeight或getComputedStyle(document.body).opacity - 变量定义在哪,就查哪:
--theme-color定义在.dark-theme上,就得传el.closest('.dark-theme'),不能传document.documentElement - 返回值带首尾空格(如
" #007bff "),不.trim()就会判断失败 - 真机调试时,Network 面板要确认含变量的 CSS 文件 HTTP 状态码是 200;iOS 12 常因 HTTPS 混合内容拦截导致
:root变量加载失败
@supports (color: var(--x)) 检测始终为 false
因为 setProperty() 设置的变量只存在于运行时 DOM,不会写入 CSSOM,浏览器构建时压根没扫描到这个变量声明。
-
@supports是编译时检测,只认静态 CSS 文件中明确定义的变量,对 JS 动态赋值完全无感 - 错误写法:
@supports (--x: red)—— 所有浏览器都不认,语法非法 - 正确写法:
@supports (color: var(--x)),变量名可以是任意合法名(比如--_),不需要真实存在 - PostCSS 插件(如
postcss-custom-properties)也只处理静态定义,对 JS 注入的变量不可见
var() 在 @keyframes 或 ::before/::after 中不生效
iOS Safari 15.6 之前版本根本不解析这些上下文中的 var(),整条规则被静默跳过,连 warning 都没有。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
立即学习“前端免费学习笔记(深入)”;
-
@keyframes中禁止直接使用var(--x),规范要求只能用字面量或calc(var(--x)),且变量必须定义在动画触发元素自身或其祖先上(如.slide:nth-child(1) { --dist: 120px; }) - 伪元素不自动继承父元素变量作用域,
.box::before { background: var(--bg); }必须配合兜底:.box { background: #f0f0f0; } - 首次渲染时 Safari 对伪元素中变量的计算比 Chrome 晚一帧,需设置后立即触发重排:
getComputedStyle(el).opacity - 避免在伪元素里用
var()驱动transition或animation,Safari 会拒绝启动
低版本 Safari(12–14)中 var() 被整条忽略
不是渲染异常,是语法层面不识别——遇到 var(--x) 就当无效声明跳过,连后备值 var(--x, #fff) 都不会进入解析流程。
- 后备值只在支持
var()语法的浏览器中生效;Safari 12–14 连函数名都通不过,#fff根本不会被读取 - 必须前置无条件 fallback:
background-color: #007aff;写在前面,再用@supports (color: var(--x))包住变量声明 - PostCSS 降级只对满足硬性条件的变量起作用:定义在
:root、值为静态常量、定义与使用在同一文件 - 真机验证比本地预览重要十倍:模拟器和 DevTools 会掩盖真实问题,Safari 旧版本对变量的丢弃是彻底的、无日志的
最易被忽略的是:Safari 对“变量何时可被读取”的判断极保守——它不等 JS 设置完就走 CSS 解析流程,也不重试。靠 JS 动态注入变量再指望 CSS 立即响应,在 Safari 里大概率失败。

















