FORMA
博客 / 教程
教程 · 阅读约 3 分钟 · 23 次阅读 · 发布于 2026-09-27 · FORMA 团队

CSS 过渡与关键帧:动画的两种写法

transition 管「从 A 到 B」,animation 管「一段编排」。选对写法,代码少一半。

CSS 动画只有两条路:transition(过渡)和 animation(关键帧)。新手最容易犯的错是用 transition 硬凑多段动画,或拿 animation 做简单的悬停反馈。判断标准一句话:状态之间的渐变用 transition,自带时间轴的编排用 animation。

transition:状态之间的桥

transition 只描述「属性从当前值到目标值怎么变」,它自己不定义动画内容。触发方式:类名切换、:hover、媒体查询变化、JS 改样式。

.card { transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 200ms ease; }
.card:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgba(0,0,0,0.12); }

三个要点:

animation:自带剧本

animation 用 @keyframes 定义关键帧,浏览器自动补间。适合多段动画、循环动画、以及不依赖交互的入场动画。

@keyframes fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}
.reveal { animation: fade-up 400ms cubic-bezier(0.22, 1, 0.36, 1) both; }

交错入场:stagger 的两种实现

列表逐项出现,transition 和 animation 各有写法。

transition 版(依赖 JS 或延迟类名):

.item { opacity: 0; transform: translateY(12px); transition: all 300ms ease; }
.item.in { opacity: 1; transform: none; }

JS 逐个加 .in,间隔 60ms。好处是可以用 IntersectionObserver 做「滚到才出现」。

animation 版(纯 CSS,借助变量):

.item { animation: fade-up 400ms ease both; animation-delay: calc(var(--i) * 60ms); }

HTML 里给每项写 style="--i:0"、"--i:1"……零 JS,但一进页面就播,不管看不看得到。

性能红线:只动 transform 和 opacity

浏览器合成器只对这两个属性的动画走 GPU 加速。width、height、top、left 的动画会触发重排重绘,帧率直接崩。检查方法:Chrome DevTools 的 Performance 面板录一遍,看有没有大片的紫色(渲染)区块。

will-change 是双刃剑:只加给「正在」动画的元素,动画结束移除。全局加 will-change 会制造大量合成层,内存暴涨。

可访问性兜底

系统开了「减弱动态效果」的用户应看到即时到位的版本,FORMA 导出的动效已内置对应处理,自定义动画时保留它。

怎么选

记住分工:transition 管「交互的反馈」,animation 管「页面的表演」。两者都会写,动画的 90% 场景就覆盖了。

评论 · 0 条

还没有评论,来抢沙发。

评论经人工审核后公开;请勿提交密码、密钥等敏感信息。