其他
设计交互组件、开关、加载器与成功状态时,用微交互确认动作…
适用于为按钮、开关、图标、加载、表单成功、列表/通知变化等界面添加 200–600ms 的非阻塞微交互,以提升反馈清晰度和愉悦感。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 55/100 ×0.15
适用场景
设计交互组件、开关、加载器与成功状态时,通用
解决思路
- 将微交互动画时长控制在 200–600ms;确保既非瞬间完成,也不慢到让用户感觉等待。
- 以自然世界为参照设计运动:加入重量、惯性、回弹和安定过程,避免瞬间跳变,让运动感觉必然如此。
- 每个微交互只承担以下至少一个目的:确认动作结果、奖励里程碑、揭示信息、增加物理质感;否则删除。
- 确保微交互不延迟用户:动画与结果并行运行,不阻塞用户继续操作。
- 避免让微交互频繁重复;重复触发的动作不要每次都动画,以免变成噪音。
- 避免只为装饰而存在的动画;不传达信息的动画应移除。
- 按自然行为映射 UI:门摆动到静止对应 toggle 轻微过冲后安定。
- 水滴滴落对应列表项 stagger 分批揭示。
- 橡皮筋回弹对应 pull-to-refresh 的反弹。
- 叶子飘落对应 dismiss 时轻微 fade 加向下漂移。
- 铃铛响对应图标在触发时短暂振荡或摇晃。
- 印章压纸对应内部元素位移,例如 icon 轻推,但不要移动按钮边界。
- 图标动画:触发时用动画而非静态替换,更鲜明地表达状态变化。
- Checkmark draw-on:完成时让对勾从起点绘制到终点;使用 stroke-dasharray 和 stroke-dashoffset,例如 .checkmark path { stroke-dasharray: 20; animation: check-draw 300ms ease-out forwards; },@keyframes check-draw from stroke-dashoffset:20 to 0。
- Heart pulse on like:点赞时先 scale(1.25) 再回到 scale(1)。
- Hamburger 到 close morphing:菜单打开时让线条动画成 ×。
- Bell shake on notification:通知时对铃铛图标做短暂振荡旋转。
- Loading spinner:用带缓动的旋转而不是 linear;spring rotation 显得有生命,linear 显得机械。
- Toggle/switch 要像物理开关,不是简单状态切换。
- Toggle thumb 使用 transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1),checked 时 translateX(20px),让滑块轻微过冲再安定。
- 在真正的完成时刻标记成功:表单提交、onboarding 步骤完成、目标达成。
- 成功反馈用对勾绘制动画。
- 对高价值里程碑(首次购买、创建账户、达成目标)使用轻量 confetti;必须克制,绝不用于常规动作。
- 进度条完成时使用绿色填充过渡。
- 统计数字到达最终值时使用 number count-up。
- 手风琴、tooltip、popover 打开时使用小幅 reveal,而不是瞬间出现。
- 手风琴内容用 overflow:hidden、max-height:0 到 max-height:500px(宽松上限)过渡,例如 transition: max-height 250ms ease-out;内容像被重力拉下一样滑入,不要闪烁出现。
- 按钮在 hover、focus、click 时绝不改变外部尺寸或布局位置。
- 按钮反馈用 background-color 和 box-shadow 过渡,例如 transition: background-color 150ms ease-out, box-shadow 150ms ease-out。
- 按钮 hover 用 --color-brand-600 做细微色相或亮度变化。
- 按钮 active 用 --color-brand-700 加深对比,并用 inset 0 2px 4px rgba(0,0,0,0.1) 内阴影制造深度,不要缩放。
- 通过颜色、内部阴影或内部元素微动画(如箭头右移 2px)传递反馈,且不影响按钮占位。
- Skeleton 到 content 不要闪入;内容加载后在 skeleton 上做 150–200ms fade-in,让骨架溶解、内容到达。
- 使用 @keyframes fade-in from opacity:0 to opacity:1 实现内容淡入。
- 对不在用户焦点区域的变化(change blindness)用轻微动画引导视线。
- Notification Badge Bloom:新通知到达时让 badge 短暂 scale 到 1.2 再回 1.0。
- Background Highlight Fade:列表项更新或新增行时,用品牌色轻染背景,再在 1–2 秒内淡到透明。
- Subtle Shake:对侧边栏或工具栏项做 2–4px 水平短暂摇晃,吸引注意但不激进。
- 远程变化提示动画必须非循环;一旦吸引到视线就停止运动,避免永久分心。
- 遵守组件稳定性神圣规则:交互元素尤其按钮必须布局稳定。
- 禁止在按钮 hover/click 使用 transform: scale();会导致视觉振动和软塌感。
- 禁止使用会改变元素相对相邻元素位置的 translate 或 margin。
- 记住布局稳定性的原因:UI 在光标下移动会不可预测,稳定才显得专业、结实。
- 状态用 transition,序列用 keyframes:hover、focus、active、selected 等状态使用 transition,因为 transition 可被中断并能从当前位置反向。
- 为分阶段入场或自主循环保留 @keyframes;keyframe 不能中断,会播放到底再跳回。
- 明确声明过渡属性,不要用 transition: all;只写会动的属性,如 transition-property: opacity, scale; transition-duration: 200ms; transition-timing-function: cubic-bezier(0.2, 0, 0, 1)。
- 避免 transition: all 触发意外布局属性重排,也避免无关 class 导致组件滑动。
- will-change 作为最后手段:只在看到首帧卡顿时添加,仅用于 transform、opacity 或 filter,并在动画结束后移除。
- 不要广泛使用 will-change;它会保留合成层,内存成本可能超过收益。
- 微交互是调味料不是主菜:每个触发器只播放一次,例如保存时对勾动画一次,而不是每次 render 都播放。
- 对重复动作跳过动画:批量删除 50 项不要逐个播放 50 次。
- 不使用阻塞动画:用户必须能立即继续;动画与结果并行,而不是代替结果。
- 始终尊重 prefers-reduced-motion;使用 @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }。
- 对每个交互自问:它让结果更清晰,还是只是让界面更忙?如果是后者就删除。
- 复查:按钮和交互元素在 hover/click 时是否完全稳定,无尺寸变化、无位移。
- 复查:每个微交互是否确认动作、奖励里程碑或帮助理解。
- 复查:时长是否在 200–600ms。
- 复查:运动是否参考自然物理(spring、ease-out、overshoot)而非 linear。
- 复查:动画是否非阻塞,用户能立即继续。
- 复查:是否尊重 prefers-reduced-motion。
- 复查:高成本庆祝(confetti、bloom)是否只留给真正里程碑。
- 复查:动画图标是否清晰传达其代表的状态变化。
- 复查:toggle/switch 是否使用 spring easing curve 而非 linear。
- 复查:焦点区域之外的远程变化是否用短暂、非循环动画引导视线。
适用边界 · 注意事项
- 当动画会延迟或阻塞用户下一步操作,或只是重复噪音、纯装饰不传达信息时,不要使用微交互。
- 不要对常规动作或批量重复动作使用高成本庆祝(如 confetti、badge bloom、逐项动画);它们只适合真正的里程碑。
- 不要在按钮 hover/click 时用 transform: scale() 或 translate/margin 改变外部尺寸或位置;这违反组件稳定性规则。