原生 css 自定义属性在 ios 14.5+、android chrome 72+ 等新版本中稳定支持,但 ios 13.4–14.4 和 android 4.4–7 webview 会静默忽略 var() 导致样式失效;fallback 必须为字面量值且需双写声明,动态修改需手动触发重排,构建时应避免全量转译,优先放弃低占比旧系统支持。

原生 CSS 自定义属性(--my-color)在 iOS 14.5+、Android Chrome 72+、Samsung Internet 10.2+ 中已稳定支持,无需 polyfill;但 iOS 13.4–14.4 和 Android 4.4–7 的 WebView 会静默忽略未声明的变量,导致样式失效——这不是语法错误,而是运行时取值为 unset。
移动端不支持自定义属性的典型表现
你写好 :root { --primary: #333; },然后在按钮上用 color: var(--primary);,结果文字仍是黑色或继承默认色。这不是选择器没匹配,而是浏览器根本没解析 var() 函数,直接跳过整条声明。常见于:
- iOS Safari 13.4–14.4:
var(--x)返回unset,且不报错 - Android 4.4–6.0 WebView(如旧版微信内置浏览器):完全忽略含
var()的整条 CSS 规则 - UC 浏览器 12.x 及更早版本:对嵌套
var(var(--x))或 fallback 写法支持不稳定
必须写的 fallback 写法
不能只依赖 var(--color),必须提供降级值。注意 fallback 不是“备选变量”,而是字面量值:
.btn {
color: #333; /* fallback 必须是具体值 */
color: var(--primary, #333); /* iOS 13.4+ 才会读这行 */
}
错误写法:color: var(--primary, var(--fallback)); —— iOS 14.0 之前不支持 fallback 里再套 var()。
关键点:
- fallback 值必须是合法 CSS 值(如
#000、16px、bold),不能是另一个变量名 - 同一属性写两遍,先写 fallback,再写
var(),靠层叠覆盖 - 不要用
!important干扰 fallback 优先级
动态修改自定义属性的兼容陷阱
用 JavaScript 改 document.documentElement.style.setProperty('--size', '18px') 在 iOS 14.5+ 没问题,但在 iOS 13.4–14.4 中,修改后不会触发重绘,UI 不更新。
实操建议:
- 改完属性后手动触发重排:
getComputedStyle(document.documentElement).transform(空读取) - 避免高频修改(如 scroll 事件里反复 setProperty),iOS 13–14 下性能极差
- Android 4.4 WebView 根本不支持
setProperty,需改用 class 切换 + 预设 CSS 规则
构建时是否该用 PostCSS 插件转译?
别用 postcss-custom-properties 全量转译。它会把所有 var(--x) 替换成硬编码值,失去运行时灵活性,且无法处理 JS 动态修改场景。
真正需要的是条件性编译:
- 仅对明确要兼容 iOS 13.4–14.4 的项目,用插件转译关键变量(如主题色、字号),保留其他动态变量不转
- 转译后务必检查 fallback 是否被覆盖(插件可能误删 fallback)
- Webpack/Vite 中启用
targets: { ios: '13.4' }后,Babel 不会碰 CSS,所以 CSS 转译必须单独配
最省事的做法:放弃 iOS 13.x 支持(2026 年其全球占比已低于 0.7%),专注写干净的 var() + fallback,把兼容成本留给真正需要的老设备客户。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











