
字节笔记本
2026年10月24日 · 约 7 分钟读完
动画审美也能装进 Skills:AI 写的界面终于“感觉对了”
你让 AI 帮你写一个弹窗动画,它多半会给你一句 transition: all 300ms。功能上没错,但元素凭空出现、又凭空消失,看起来像间“能用的毛坯房”。问题不在 AI 的编码能力,而在于它没有设计工程师的审美判断。Emil Kowalski(Sonner、Vaul 的作者,先后在 Vercel 和 Linear 做设计工程)把多年积累的 UI 与动画原则开源成了 Skills 仓库,让 Claude Code、Codex、Cursor 这类 Coding Agent 写界面时,具备接近资深设计工程师的判断力。

这个仓库现在长什么样
仓库 emilkowalski/skills 创建于 2026 年 3 月,目前 4.9 万星、MIT 协议。最早靠三个核心 Skills 出圈,如今已扩到 15 个:主 Skill emil-design-eng 之外,还有从零构建动画的 animate、面向 React Native 的 animate-expo、审计整个代码库动画的 improve-animations、专治掉帧的 animation-performance、把苹果设计原则翻译给 Web 的 apple-design、让网页在手机上更像原生应用的 mobile-native、用最坏数据搞垮自己 UI 的 break-ui 等。

安装只要一行命令:
npx skills@latest add emilkowalski/skillsREADME 说得很直白:Agents don't have great taste。这些 Skills 列出 agent 可能犯的每一种小错并解释怎么改,按作者的说法,这是“在一片 slop 里脱颖而出”的捷径。
三个核心 Skills 的分工
| Skill | 作用 | 回答的问题 |
|---|---|---|
| emil-design-eng | 设计工程哲学 + 动画决策框架 | 该不该加动画、加什么动画 |
| review-animations | 以严格标准审查动画代码 | 这段代码哪里不对、怎么改 |
| animation-vocabulary | 把模糊感受翻译成专业术语 | 用户说的“弹一下”叫什么 |
工作顺序很清晰:先建立决策框架,再审查代码,最后精准描述动效。
动画需要理由,频率决定强度
每条动画都要回答“它为什么要动”。空间一致性(toast 从同一方向进出)、状态指示、解释关系、防止突兀、按下反馈都是合理理由;如果理由只是“看起来很酷”而且高频出现,就该删。
更实用的是按使用频率定强度:
| 使用频率 | 场景 | 策略 |
|---|---|---|
| 每天 100+ 次 | 快捷键、命令面板 | 禁止动画 |
| 每天几十次 | hover、列表导航 | 删除或大幅简化 |
| 偶尔 | 弹窗、抽屉、toast | 标准动画 |
| 罕见/首次 | onboarding、庆祝反馈 | 可以给点惊喜 |
很多项目正好做反了:高频交互加了花哨动画,首次体验反而平淡无奇。
最值得抄走的技术规则
Easing:进场用 ease-out,屏内移动用 ease-in-out,hover 和颜色变化用 ease,恒速运动用 linear。UI 动画任何情况下禁用 ease-in,开头慢就是让用户感觉延迟。默认曲线太弱,要用 cubic-bezier 这类强曲线。
时长:UI 动画控制在 300ms 内。按钮反馈 100 至 160ms,Tooltip 与小弹层 125 至 200ms,下拉框 150 至 250ms,模态框和抽屉 200 至 500ms。
物理正确性:永远不要从 scale(0) 开始,现实里没有东西凭空出现,应该用 scale(0.95) 加 opacity: 0;popover 的 transform-origin 要指向触发按钮(模态框例外);按钮按下必须有 scale(0.97) 反馈。
性能:只动画 transform 和 opacity;别碰 width、height、top、left;Framer Motion 的 x/y/scale 简写不走硬件加速,要写完整的 transform 字符串;预定动画用 CSS,动态可打断的用 JS。
无障碍:尊重 prefers-reduced-motion,做法不是全部关掉,而是保留 opacity 与颜色变化、去掉位移;hover 动画包进 @media (hover: hover) and (pointer: fine),避免触屏误触发。
两个立竿见影的用法
review-animations 的输出是一张 Before / After / Why 表:
| Before | After | Why |
|---|---|---|
transition: all 300ms | transition: transform 200ms ease-out | 精确指定属性,避免 all 触发非 GPU 动画 |
transform: scale(0) | transform: scale(0.95); opacity: 0 | 现实中没有东西凭空出现 |
animation-vocabulary 是动效术语反查表:“iOS 拉到底弹回来”叫 Rubber-banding,“元素从按钮里长出来”叫 Origin-aware animation,“那个弹一下的效果”叫 Pop in。设计师和工程师沟通、给 AI 下精确指令时都用得上。
写在最后
这套 Skills 的价值不是教你怎么写动画,教程已经够多了;它把资深设计工程师的审美判断,变成了 AI 可以执行的决策框架和审查标准。动画不是“让它动起来”,而是“让它感觉对”,这句话值得贴在每个 coding agent 的上下文窗口里。
作者本人就是这套方法论的活样本:toast 库 Sonner 和抽屉组件 Vaul 都出自他手,正是这些“感觉对了”的细节让它们成为 React 生态里最流行的选择之一。




