用途
本指南用于在 Web 界面中编写、审查或实现动画时提供参考,基于 Emil Kowalski 的教学内容、其开源库(Sonner、Vaul)以及 animations.dev 课程整理。它包含 58 条规则,分为 8 个类别,并按影响程度划分优先级。
适用时机包括:为 React 组件添加动画、选择缓动曲线或时间值、实现基于手势的交互(滑动、拖拽)、构建 toast 通知或抽屉组件、优化动画性能、确保动画无障碍,以及用 Tailwind CSS v4 工具类表达上述内容(见 tw- 类别)。
规则类别与优先级
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 缓动选择 | CRITICAL | ease- |
| 2 | 时间与时长 | CRITICAL | timing- |
| 3 | 属性选择 | HIGH | props- |
| 4 | 变换技巧 | HIGH | transform- |
| 5 | 交互模式 | MEDIUM-HIGH | interact- |
| 6 | 策略性动画 | MEDIUM | strategy- |
| 7 | 无障碍与打磨 | MEDIUM | polish- |
| 8 | Tailwind v4 工具类 | MEDIUM | tw- |
主要能力(规则速查)
1. 缓动选择(CRITICAL)
- ease-out-default:默认使用 ease-out 缓动
- ease-custom-curves:优先使用自定义 cubic-bezier 而非内置 CSS 曲线
- ease-in-out-onscreen:屏幕内移动使用 ease-in-out
- ease-spring-natural:自然运动使用弹簧动画
- ease-spring-config:用 duration 和 bounce 配置弹簧
- ease-ios-drawer:抽屉组件使用 iOS 风格缓动
- ease-context-matters:缓动需匹配动画语境
2. 时间与时长(CRITICAL)
- timing-300ms-max:UI 动画保持在 300ms 以内
- timing-faster-better:更快的动画提升感知性能
- timing-asymmetric:按下与释放使用非对称时长
- timing-tooltip-delay:首次 tooltip 延迟,后续即时
- timing-drawer-500ms:抽屉动画使用 500ms 时长
3. 属性选择(HIGH)
- props-transform-opacity:只对 transform 和 opacity 做动画
- props-hardware-accelerated:主线程繁忙时使用硬件加速动画
- props-will-change:用 will-change 防止 1px 偏移
- props-avoid-css-variables:拖拽动画避免使用 CSS 变量
- props-clip-path-performant:用 clip-path 实现不触发布局的揭示效果
4. 变换技巧(HIGH)
- transform-scale-097:按下时按钮缩放到 0.97
- transform-never-scale-zero:不要从 scale(0) 开始动画
- transform-percentage-translate:translateY 使用百分比值
- transform-origin-aware:让动画感知变换原点
- transform-scale-children:缩放变换会影响子元素
- transform-3d-preserve:3D 变换效果使用 preserve-3d
- transform-starting-style:用 @starting-style 动画化进入状态
5. 交互模式(MEDIUM-HIGH)
- interact-interruptible:让动画可被中断
- interact-momentum-dismiss:使用基于动量的关闭
- interact-damping:在边界处对拖拽施加阻尼
- interact-scroll-drag-conflict:解决滚动与拖拽冲突
- interact-snap-points:实现感知速度的吸附点
- interact-friction-upward:允许带摩擦的向上拖拽
- interact-pointer-capture:拖拽操作使用指针捕获
- interact-multitouch:拖拽时忽略多余触点
- interact-touch-hover:将 hover 动画限制在指针媒体查询之后
6. 策略性动画(MEDIUM)
- strategy-keyboard-no-animate:键盘触发的操作不做动画
- strategy-frequency-matters:动画前考虑交互频率
- strategy-purpose-required:每个动画都必须有目的
- strategy-feedback-immediate:所有操作都提供即时反馈
- strategy-marketing-exception:营销站点是例外
- strategy-cohesion:让动效匹配组件个性
- strategy-review-fresh-eyes:用慢动作并在次日复查动画
7. 无障碍与打磨(MEDIUM)
- polish-reduced-motion:尊重 prefers-reduced-motion
- polish-opacity-fallback:用 opacity 作为减弱动效的回退
- polish-framer-hook:在 Framer Motion 中使用 useReducedMotion hook
- polish-dont-remove-all:减弱动效时保留温和动画
- polish-blur-bridge:用模糊衔接动画状态
- polish-clip-path-tabs:标签页切换使用 clip-path
- polish-toast-stacking:用缩放和偏移实现 toast 堆叠
- polish-scroll-reveal:在合适阈值触发滚动动画
- polish-hover-gap-fill:填充可 hover 元素之间的空隙
- polish-stagger-children:错开子元素动画以形成编排
8. Tailwind v4 工具类(MEDIUM) 用恰当的 Tailwind CSS v4 工具类表达上述原则,仅适用于 Tailwind v4 项目;上述原生 CSS 与 Framer Motion 规则仍是事实来源。
- tw-ease-duration-defaults:显式设置 ease-out 和低于 300ms 的时长
- tw-custom-easing-theme:将自定义缓动曲线注册为 @theme token
- tw-press-scale:用 active:scale-[0.97] 实现按钮按下反馈
- tw-asymmetric-timing:用 active:duration 拆分按下与释放时长
- tw-starting-enter:用 starting: 变体动画化进入状态
- tw-reduced-motion:将运动限制在 motion-safe / motion-reduce 之后
- tw-origin-aware:用 origin-* 工具类设置 transform-origin
- tw-will-change:将 will-change-transform 限定在活动手势期间
关键数值参考
| 数值 | 用途 |
|---|---|
| cubic-bezier(0.23, 1, 0.32, 1) | UI 交互的强 ease-out |
| cubic-bezier(0.77, 0, 0.175, 1) | 屏幕内移动的强 ease-in-out |
| cubic-bezier(0.32, 0.72, 0, 1) | iOS 风格抽屉/面板动画 |
| scale(0.97) | 按钮按下反馈 |
| scale(0.95) | 最小进入缩放(绝不用 scale(0)) |
| 200ms ease-out | 标准 UI 过渡 |
| 300ms | UI 动画最大时长 |
| 500ms | 抽屉动画时长 |
| 0.11 px/ms | 动量关闭的速度阈值 |
| 100px | 滚动揭示的视口阈值 |
| 14px | toast 堆叠偏移 |
按元素选择时长
根据元素被看到的频率和移动幅度选择时长,UI 动画保持在 300ms 以内。
| 元素 | 时长 |
|---|---|
| 按钮按下反馈 | 100–160ms |
| Tooltip、小型弹出层 | 125–200ms |
| 下拉菜单、选择器 | 150–250ms |
| 模态框、抽屉 | 200–500ms |
| 营销/说明性内容 | 可以更长 |
参考文件
| 文件 | 说明 |
|---|---|
| references/_sections.md | 类别定义与排序 |
| assets/templates/_template.md | 新规则模板 |
| metadata.json | 版本与参考信息 |
限制
资料未提供该指南的安装命令、具体代码实现、收费或价格信息、支持的平台范围,以及实际使用效果数据,这些内容暂未提供。