不能只用一个--duration变量,因为交互节奏不同需多档时长:--transition-fast(0.18s)用于按钮悬停等微交互,--transition-normal(0.3s)用于常规状态切换,--transition-slow(0.45s)用于模态框等重量级变化;CSS变量不可动画,必须在元素上显式声明transition并严格对齐属性、时长与缓动函数。

为什么不能只用一个 --duration 变量
单一变量如 --duration: 0.3s 看似统一,实则掩盖了交互节奏差异。按钮悬停需要快速反馈(0.18s),而模态框入场需视觉缓冲(0.45s),硬套同一值会导致部分动画“卡顿感”或“飘忽感”。更关键的是,CSS 变量本身不可动画,--duration 不会自动触发过渡——真正起作用的是它被用在 transition 声明里的那一刻。
必须按语义预设多档时长变量
在 :root 中定义明确用途的变量,而不是抽象的“基础时长”:
:root {
--transition-fast: 0.18s;
--transition-normal: 0.3s;
--transition-slow: 0.45s;
}-
--transition-fast用于高频微交互:按钮 hover、图标缩放、开关 toggle -
--transition-normal用于常规状态切换:导航展开、折叠面板、表单项 focus -
--transition-slow用于重量级变化:模态框入场/退场、页面路由切换、加载遮罩显隐
不要试图用乘法动态计算(比如 calc(var(--base) * 1.2)),CSS 变量不支持运行时运算,且语义模糊。
transition 声明必须绑定到具体属性,不能只改变量
常见错误是只更新 --transition-normal,却没在对应元素上重写 transition 规则。变量只是占位符,浏览器只对最终解析出的原生属性(如 background-color、transform)做插值动画。
立即学习“前端免费学习笔记(深入)”;
正确写法示例:
button {
transition: background-color var(--transition-fast) ease,
transform var(--transition-fast) ease;
}
.modal {
transition: opacity var(--transition-slow) cubic-bezier(0.25, 0.46, 0.45, 0.94),
transform var(--transition-slow) cubic-bezier(0.25, 0.46, 0.45, 0.94);
}- 逗号分隔的每一对必须严格对齐:
property、duration、timing-function - 顺序错一位(比如把
transform的 duration 写在opacity的 timing-function 位置)会导致整条声明失效 - 避免用
all,否则box-shadow或border-color的微小变化也会触发重绘,影响性能
主题切换时过渡动画容易失效的根源
当通过 class 切换主题(如 body.dark)并依赖 CSS 变量更新颜色时,很多人忘了:变量变了,但 transition 必须作用于实际变化的属性(如 color、background-color),且声明必须写在**使用这些属性的元素上**,而非 :root 或 body。
例如:
.card {
color: var(--text-primary);
background-color: var(--bg-surface);
/* ✅ transition 必须在这里声明 */
transition: color var(--transition-normal), background-color var(--transition-normal);
}- 如果只在
:root里改--text-primary,但没在.card上写transition,颜色切换就是瞬时的 - 媒体查询中覆盖变量时,也要同步检查对应元素的
transition是否仍有效(比如@media (prefers-reduced-motion)下应设transition: none)
变量管理本身不难,难的是让每个用到它的 transition 声明都保持语义清晰、属性对齐、作用域准确——漏掉任何一个环节,动画就静音了。


















