Skip to content
返回设计中心

动画与动效系统

使动效一致、有目的、reduced-motion 安全的时长、缓动、弹簧令牌。

设计令牌进阶

为什么

临时过渡(这里 300ms、那里 150ms、linear 缓动)感觉随机并可能引发前庭问题。带语义缓动的动效阶使动效有目的并尊重 prefers-reduced-motion。

Tokens Studio(原 Figma Tokens)有 50 万以上安装量,W3C 设计令牌格式模块即将成为候选推荐。令牌从单一来源实现暗色模式、多品牌主题和平台一致性。

何时使用

有 3+ 动画组件时定义动效令牌。若临时粘贴 cubic-bezier 字符串,立即合并为命名缓动。

如何做

1. 时长阶 — instant=100、fast=150、normal=250、slow=400、slower=600(ms) 2. 缓动 — 入场 ease-out、出场 ease-in、状态变化 ease-in-out 3. 弹簧令牌 — 物理基础:stiffness=300、damping=30(framer-motion) 4. 语义动效 — fade、slide-up、scale-in,各 = 时长 + 缓动 + 属性 5. 减弱动效 — 包在 @media (prefers-reduced-motion: reduce) → duration: 0 6. 令牌 — --duration-{fast|normal|slow}、--ease-{out|in|in-out} 7. 错峰 — 子项延迟 = index × 50ms,总上限 300ms

示例

/* motion-tokens.css */ :root { --duration-fast: 150ms; --duration-normal: 250ms; --duration-slow: 400ms; --ease-out: cubic-bezier(0, 0, 0.2, 1); --ease-in: cubic-bezier(0.4, 0, 1, 1); --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); } /* 语义动效 — 入场 */ .fade-in { animation: fade-in var(--duration-normal) var(--ease-out); } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } /* 减弱动效 — 禁所有动画 */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } // framer-motion — 弹簧带减弱动效守卫 const motion = useReducedMotion() ? { duration: 0 } : { type: "spring", stiffness: 300, damping: 30 }; <motion.div animate={{ opacity: 1 }} transition={motion} />

常见问题

  • ⚠UI 用 linear 缓动 — 感觉机械廉价;入场用 ease-out
  • ⚠无减弱动效守卫 — 前庭用户因视差/旋转恶心
  • ⚠处处 300ms — hover 太慢、页面转场太快,无语义区分

最佳实践

  • ✓入场用 ease-out、出场用 ease-in — 匹配用户动效预期
  • ✓始终尊重 prefers-reduced-motion — 这是 WCAG 2.3.3 且 5 行 CSS 守卫
  • ✓错峰总上限 300ms — 超过则序列感觉慢且戏剧化

常见问题解答