CSS变量无法直接用于cubic-bezier()中,需用@property声明<easing>类型(Chrome117+/Safari16.4+),否则报Invalid property value;旧版浏览器应预设类名降级。

直接用 CSS 变量传参会报错
你不能写 transition: transform 0.3s cubic-bezier(var(--x1), var(--y1), var(--x2), var(--y2))——CSS 解析器会直接拒绝,报 Invalid property value。因为 cubic-bezier() 是函数调用,不是属性值计算上下文,var() 在这里不参与运行时求值,而是被当作未解析的字符串丢弃。
用自定义属性 + @property 做类型声明(Chrome 117+ / Safari 16.4+)
真正能“动态控制”的路径是结合 @property 和 transition-timing-function 的 CSS 属性注册机制。前提是你要接受浏览器兼容性限制:Firefox 尚未支持 @property 用于非数值型属性(如缓动函数),所以目前仅适用于较新版本的 Chromium 和 Safari。
- 必须先用
@property显式声明变量为<easing>类型,否则无效 - 声明后,该变量才能被
transition-timing-function或animation-timing-function接收 - 变量值仍需是合法的
cubic-bezier()字符串,不能拼接或计算
示例:
@property --ease-spring {
syntax: '<easing>';
inherits: false;
initial-value: cubic-bezier(0.17, 0.67, 0.83, 0.67);
}
.card {
transition: transform 0.35s var(--ease-spring);
}
.card:hover {
transform: translateY(-4px);
}
降级方案:用 :is() + 多类名切换代替变量
在需要兼容旧版浏览器(比如 iOS 15/Safari 15、Android WebView)时,别碰 @property。更稳妥的做法是预设几组常用曲线,用类名开关:
立即学习“前端免费学习笔记(深入)”;
- 定义多个带语义的类:
.ease-ios、.ease-bounce、.ease-snappy - 每个类内硬编码对应的
cubic-bezier()值,确保 y 坐标都在 [0,1] 内(避免 Safari ≤13 静默降级) - 用 JS 切换类名:
el.classList.replace('ease-ios', 'ease-bounce')
这样既可控,又不会因变量解析失败导致整段 transition 失效。
别试图用 calc() 或字符串拼接生成贝塞尔值
所有尝试绕过语法限制的操作都会失败:
-
calc()只作用于数值,不能产出函数调用 - CSS 不支持模板字面量或字符串连接,
content: "cubic-bezier(" var(--x1) "," ...)没有意义 - 即使配合
@layer或@container,也无法改变cubic-bezier()的解析时机
真正需要运行时生成曲线的场景(比如根据拖拽速度动态调整回弹强度),应该交给 JavaScript 控制 animation-timing-function 的 CSSOM 设置,而不是依赖纯 CSS 变量。


















