【免费下载链接】design-motion-principles
A motion design skill with two modes — build interactive components with purposeful motion, or audit existing animations. Context-aware, per-designer guidance distilled from the published work of Emil Kowalski, Jakub Krehel, and Jhey Tompkins.
design-motion-principles 是一个专为 Web 界面动效设计的技能包,它沉淀了 Emil Kowalski、Jakub Krehel 和 Jhey Tompkins 三位知名设计工程师的公开方法论,既能帮你构建带"目的性动效"的交互组件,也能审计现有动画。本文聚焦它的三大高级技巧:FLIP 共享布局、scroll-driven 滚动驱动动画与@property自定义属性动画,带你从新手视角快速上手这些 2026 年最实用的动效技术 🚀
为什么是这三项技术?
这个项目把动效知识分成"判断力"和"代码"两层:设计师哲学文件教你该不该动、动多细,而统一的配方库 motion-cookbook.md 提供全部可落地的实现代码。
三项高级技巧分别来自不同设计师的专长:
| 技巧 | 出处 | 解决的问题 |
|---|---|---|
| FLIP 共享布局 | Jakub Krehel | 组件间(卡片→弹窗)的平滑空间过渡 |
| scroll-driven 动画 | Jhey Tompkins | 滚动动画与滚动速度脱钩,控制播放时长 |
@property类型声明 | Jhey Tompkins | 让 CSS 变量能被平滑插值,做出曲线运动 |
三者都不需要额外依赖,纯 CSS/React 生态即可实现,这正是它们被称为"高级技巧"的原因。
FLIP 共享布局:让卡片"飞"进弹窗
什么是 FLIP?
FLIP(First、Last、Inverse、Play)是一种空间连续性动画技术:浏览器先记录元素的位置,再计算位置差异并反向补偿,最后播放过渡。用户看到的不是"一个元素消失、另一个出现",而是同一个元素平滑地移动变形——比如商品卡片点击后无缝展开为详情弹窗。
用 layoutId 一行搞定
在 React 生态中,Motion(Framer Motion)的layoutId属性封装了整套 FLIP 逻辑。核心用法极简:两个不同位置的组件,只要共享同一个layoutId,就会自动做布局过渡:
// 列表中的小卡片 <motion.div layoutId="card" className="small-card" /> // 详情中的大卡片 <motion.div layoutId="card" className="large-card" />配方详情见 motion-cookbook.md。项目总结的四条最佳实践值得记住:
- 放在 AnimatePresence 之外——把
layoutId元素放进AnimatePresence会让 initial/exit 动画与布局动画打架,透明度叠加会很难看 - 多个元素各自用唯一
layoutId,可并行动画 - 支持高度、宽度、位置甚至组件类型的过渡(card → modal)
- 配合
bounce: 0的 spring 曲线,过渡专业而不浮夸
什么时候该用?
按 jakub-krehel.md 的决策框架:共享布局动画属于"空间关系"类功能性动画——它告诉用户"这个大弹窗就是刚才那张卡片变的"。在电商商品详情、地图标记展开等场景收益最大;但如果用户每天触发几百次(比如表格行展开),按 Emil 的"频率闸门"原则应该直接用即时切换,不做动画。
scroll-driven 动画:让滚动控制触发,而非控制速度
核心问题:滚动快慢 ≠ 动画快慢
CSS 原生的 scroll-driven animation(animation-timeline: scroll())把动画进度直接绑定到滚动位置。这带来一个反直觉的问题:用户滚得快,动画就播得快;滚得慢,动画就拖得长。对大多数 UI 来说这感觉是错的——你希望动画在滚动到某个位置时"开始",然后按固定时长播放完。
双动画协作模式
cookbook 第 14 节给出了精妙的解法(源码参考):
- 触发动画:scroll-driven,只负责在元素进入视口时切换一个自定义属性
- 主动画:传统固定时长动画,通过 Style Query 在触发后启动
两个动画协作,就把"滚动速度"和"动画时长"彻底解耦——无论用户多快滑过,动画始终以设计好的节奏播放 🎬
别忘了渐进增强
并非所有浏览器都支持 scroll-driven 动画。项目的标准做法是特性检测 + 降级:
if (!CSS.supports('animation-timeline', 'scroll()')) { // 回退到 IntersectionObserver,只做"进入视口触发" }这也是 Jhey Tompkins "渐进增强"哲学的体现:先进特性负责上限,回退方案保证底线。
@property 深度实战:类型声明解锁 CSS 变量动画
痛点:CSS 变量为什么不能动画?
CSS 把未声明类型的自定义属性当作字符串处理,而字符串无法插值——只能在起点和终点之间"硬切"。所以--hue: 0到--hue: 360的过渡只会瞬间跳变。
一行 @property 解决一切
@property规则让你为变量声明类型,浏览器就知道如何平滑插值:
@property --hue { syntax: '<number>'; initial-value: 0; inherits: false; } @keyframes rainbow { to { --hue: 360; } }支持的类型包括length、number、percentage、color、angle、time、integer、transform-list——完整清单见 motion-cookbook.md 第 7 节。
高阶玩法:分解 transform 走出曲线轨迹
单个transform属性只能做直线插值,但把运动拆成两个带类型的变量,就能做弧线轨迹——这是纯 CSS 里不可能用 monolithic transform 实现的效果:
@property --x { syntax: '<percentage>'; initial-value: 0%; } @property --y { syntax: '<percentage>'; initial-value: 0%; } .ball { transform: translateX(var(--x)) translateY(var(--y)); animation: throw 1s; } @keyframes throw { 0% { --x: -500%; } 50% { --y: -250%; } /* 最高点时只改 y,x 继续推进 */ 100% { --x: 500%; } }小球会划出一道抛物线,而不是生硬地斜着飞过去 ✨ 这个"分解 transform"技巧与 jhey-tompkins.md 中"Signature Techniques"表格完全对应,是学习 CSS 动效曲线的高级入口。
另一个实用模式是作用域变量:给每个子元素定义不同的--delay,再用calc(var(--delay) * 100ms)计算动画延迟,一份 keyframes 定义就能产生整组错落有致的入场效果,避免手写 N 条动画规则。
组合实战:性能与无障碍清单
高级技巧用得好,细节决定成败。项目的 performance.md 和 accessibility.md 给出了硬规则:
性能方面⚡
- 只动画
transform/opacity/filter,永不碰width、height、top、left(触发重排) will-change只加在即将动画的 0-3 个元素上,且写具体属性;加 10 个以上 GPU 层就该重新考虑方案- 可中断场景(快速点击、拖拽)用 state 驱动的 transition,不要用 keyframes——keyframes 中途无法改目标
无障碍方面♿
prefers-reduced-motion: reduce处理是强制项,不是"之后再补"。FLIP 弹窗、scroll-driven 入场、@property彩虹动画全部要提供降级路径- 功能性动画(状态指示、空间关系)需要非动效替代方案;纯装饰动画直接移除即可
- 避免大范围缩放、旋转、视差——前庭敏感用户会真正不适
参考文件索引
| 文件 | 内容 |
|---|---|
| motion-cookbook.md | 全部动效配方:FLIP、@property、scroll-driven、easing、spring |
| jhey-tompkins.md | CSS 创新与创意实验的判断框架 |
| jakub-krehel.md | 生产级打磨:FLIP 落地与细腻度标准 |
| performance.md | will-change、GPU 分层、性能预算 |
| accessibility.md | prefers-reduced-motion 与功能/装饰动画分类 |
| create.md | Create 模式完整工作流 |
小结
FLIP 共享布局、scroll-driven 动画、@property三者看似独立,其实共享同一个内核:用现代 CSS 能力把"位置、时间、插值"三件事从 JS 手里优雅地接回来。design-motion-principles 的价值在于,它不只给你代码,还教你在什么场景用、用什么分寸用——这正是"高级技巧"和"炫技"的分界线。动手试试吧 💪
【免费下载链接】design-motion-principles
A motion design skill with two modes — build interactive components with purposeful motion, or audit existing animations. Context-aware, per-designer guidance distilled from the published work of Emil Kowalski, Jakub Krehel, and Jhey Tompkins.
相关推荐
DataEase开源BI社区版与企业版怎么选:3分钟完整选型指南
DataEase开源BI社区版与企业版怎么选:3分钟完整选型指南 DataEase是一款开源BI与数据可视化分析工具。社区版与企业版的选择,常常让团队纠结。本文
数据分析数据可视化后端前端Motion 共享布局动画"第二次关闭闪烁"问题(issue-2405)验证计划与共享栈状态源码深度解析
Motion 共享布局动画"第二次关闭闪烁"问题(issue 2405)验证计划与共享栈状态源码深度解析 本文以仓库内验证型计划 plans/issues/is
前端UI组件Motion 投影系统(Projection System)深度解析:FLIP 布局动画架构、性能瓶颈与优化路线
Motion 投影系统(Projection System)深度解析:FLIP 布局动画架构、性能瓶颈与优化路线 Motion(motion)的投影系统是实现
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考