3、CSS动画入门:transition过渡、transform变换、animation动画、@keyframes关键帧、性能与硬件加速
好,咱们进入CSS动画的世界。说实话,CSS动画是我个人觉得性价比最高的跨平台方案——你不需要引入任何第三方库,浏览器原生支持,写起来也直观。我在早期做移动端H5的时候,很多交互动效就是用CSS搞定的,流畅度完全不输原生。
这一章,咱们把CSS动画的四个核心概念讲透:transition、transform、animation、@keyframes。最后再聊聊性能和硬件加速,这可是实战中的关键。
3.1 transition:最简单的过渡动画
transition 说白了就是「状态变化时的平滑过渡」。你想想看,一个按钮从红色变成蓝色,如果没有transition,它瞬间就变了,很生硬。加上transition,它就会慢慢过渡过去,视觉上舒服很多。
基本语法长这样:
/* 简写形式 */
transition: property duration timing-function delay;
/* 实际例子 */
.button {
background-color: #ff6b6b;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: #4ecdc4;
}
这里有几个参数要注意:
- property:要过渡的属性,比如
background-color、opacity、width等。可以用all表示所有可过渡属性。 - duration:过渡时长,单位秒(s)或毫秒(ms)。我个人习惯用
0.3s作为默认值,视觉上不拖沓也不突兀。 - timing-function:缓动函数,控制动画速度曲线。常用的有
ease、linear、ease-in、ease-out、ease-in-out。 - delay:延迟多久开始过渡。
transition: opacity 0.3s ease, transform 0.5s ease-out;。我在做卡片悬停效果时经常这么用,透明度先变,位置后变,层次感就出来了。
3.2 transform:变换的魔法
transform 不是动画本身,但它为动画提供了「变化的目标值」。你可以用它来平移、旋转、缩放、倾斜元素。
常用的变换函数:
| 函数 | 作用 | 示例 |
|---|---|---|
translate(x, y) |
平移 | transform: translate(50px, 100px) |
rotate(deg) |
旋转 | transform: rotate(45deg) |
scale(n) |
缩放 | transform: scale(1.5) |
skew(deg) |
倾斜 | transform: skew(10deg, 5deg) |
注意,transform 可以组合使用:
.box {
transform: translateX(100px) rotate(30deg) scale(1.2);
}
顺序很重要!translate 后再 rotate 和 rotate 后再 translate,结果完全不同。嗯,这里要记住:变换是从右往左执行的。
transform: translate(-50%, -50%) 做居中时,如果父容器没有明确的高度,百分比计算会出问题。后来我改用 flex 布局配合 margin: auto,稳多了。
3.3 animation + @keyframes:真正的动画
transition 只能处理「开始状态 → 结束状态」的简单变化。如果你想要更复杂的多阶段动画,就得用 animation 配合 @keyframes。
@keyframes 定义动画的关键帧,animation 则控制动画如何播放。
/* 定义关键帧 */
@keyframes bounce {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-30px);
}
100% {
transform: translateY(0);
}
}
/* 应用动画 */
.ball {
animation: bounce 1s ease-in-out infinite;
}
animation 的完整属性:
- animation-name:关键帧名称
- animation-duration:动画时长
- animation-timing-function:缓动函数
- animation-delay:延迟时间
- animation-iteration-count:播放次数,
infinite表示无限循环 - animation-direction:方向,
normal、reverse、alternate等 - animation-fill-mode:动画结束后保持的状态,
forwards保持最后一帧 - animation-play-state:播放状态,
running或paused
animation-delay 的负值来让多个元素错开播放。比如三个点依次弹跳,设置 animation-delay: -0.3s、-0.6s,效果非常自然。
3.4 性能与硬件加速
好,这部分是重点。CSS动画虽然方便,但写不好照样卡成PPT。为什么?
浏览器渲染页面大致分几个阶段:JavaScript → Style → Layout → Paint → Composite。其中 Layout(重排)和 Paint(重绘)是最耗性能的。
哪些属性会触发重排?
width、height、margin、padding、top、left等display: none到block
哪些只触发重绘?
color、background-color、visibility等
哪些只触发合成(最快)?
transform、opacity
所以,我的建议是:能用 transform 和 opacity 实现的动画,绝不用其他属性。比如移动一个元素,用 transform: translateX() 代替 left,性能差距巨大。
3.5 硬件加速:让GPU帮你干活
硬件加速,说白了就是让GPU(图形处理器)来分担CPU的渲染工作。CSS中可以通过 will-change 属性或 transform: translateZ(0) 来触发。
/* 告诉浏览器这个元素要变化,提前优化 */
.card {
will-change: transform, opacity;
}
/* 或者用经典的 hack 方式 */
.card {
transform: translateZ(0);
}
will-change 不要滥用。我曾经在一个列表的每个元素上都加了 will-change: transform,结果内存占用飙升,反而更卡了。只在需要动画的元素上加,动画结束后最好移除。
硬件加速的原理是:浏览器会把元素提升到一个独立的合成层,由GPU单独处理。这样即使主线程卡顿,动画依然流畅。
但凡事都有代价——合成层过多会消耗GPU内存。移动端尤其敏感,有些低端机可能直接闪退。
3.6 实战建议总结
说了这么多,我总结几条实战中能直接用的原则:
- 简单交互用 transition:hover、focus、active 等状态变化,一行代码搞定。
- 复杂动画用 animation + @keyframes:多阶段、循环、带节奏的动画。
- 优先使用 transform 和 opacity:性能最好,不触发重排重绘。
- 谨慎使用 will-change:只在需要时加,用完记得移除。
- 测试低端设备:我在做项目时,经常用 Chrome 的 CPU 降速模拟来测试,调到 4x 或 6x 降速,卡不卡一目了然。
CSS动画入门其实不难,难的是写出既流畅又兼容的动画。下一章咱们会深入实战,看看怎么用CSS动画做出真正能用的UI动效。