在 CSS 中,实现动画效果主要有两种方式:transition(过渡)和 animation(关键帧动画)。掌握它们的区别、用法以及性能优化是前端面试的常见考点。
transition 用于在 CSS 属性值发生变化时(如 hover、class 变化),提供平滑的过渡效果。它是一种隐式过渡,需要在两个状态之间切换。
transition-property: 指定要过渡的 CSS 属性(如 width, background-color, all)。transition-duration: 过渡持续时间(如 0.3s, 300ms)。transition-timing-function: 时间曲线(如 ease, linear, ease-in-out, cubic-bezier(...))。transition-delay: 延迟开始时间。animation 配合 @keyframes 可以实现更复杂的动画效果。它不需要触发事件即可自动运行,并且可以控制循环次数、方向、暂停等。
animation-name: @keyframes 定义的动画名称。animation-duration: 持续时间。animation-timing-function: 时间曲线。animation-delay: 延迟时间。animation-iteration-count: 播放次数 (1, infinite 等)。animation-direction: 播放方向 (normal 正常, reverse 反向, alternate 往返)。animation-fill-mode: 动画结束后的状态 (none, forwards 停在最后一帧, backwards, both)。animation-play-state: 播放状态 (running, paused)。| 特性 | transition | animation |
|---|---|---|
| 触发方式 | 需要事件触发(hover, js 改 class, focus 等) | 可以自动运行,也可以通过 JS 控制 |
| 状态控制 | 只有开始和结束两个状态 | 可以定义中间的关键帧 (0%, 50%, 100%) |
| 循环 | 不能循环,触发一次执行一次 | 可以设置 iteration-count 循环播放 |
| 精细度 | 适合简单的属性变化 | 适合复杂的自定义动画效果 |
| JS 控制 | 较弱 | 较强(Running/Paused, 事件监听 animationend) |
动画性能是面试中的高频考察点,核心在于减少重排(Reflow)和重绘(Repaint),尽量利用 GPU。
浏览器通常使用 CPU 进行渲染(特别是重排和重绘)。开启硬件加速后,浏览器会将通过特定 CSS 属性的元素提升到一个独立的合成层 (Compositing Layer)。该层的变换由 GPU 处理,跳过 Layout 和 Paint 阶段,直接进行 Composite,效率极高。
如何开启? 常见触发 GPU 加速的属性:
transform: translateZ(0)transform: translate3d(0, 0, 0)will-change: transformopacity (配合动画时)始终优先对以下属性进行动画,因为它们只会触发 Composite (合成) 阶段:
transform: 处理位移 (translate)、缩放 (scale)、旋转 (rotate)。 (替代 left/top/width/height)opacity: 处理透明度显隐。 (替代 visibility/display)反例:
使用 left: 100px 动画会触发 Layout,每一帧都要重新计算布局,容易导致卡顿 (Jank)。
will-change 是一个 CSS 属性,用于告知浏览器该元素即将发生变化,让浏览器提前进行优化(如创建合成层)。
注意事项:
will-change 会导致内存飙升,反而降低性能。:hover 状态下使用。(详见上文表格)
transform: translate3d(0,0,0) 或 translateZ(0)。will-change: transform。left/top 会触发 Layout 及其之后的所有流程,消耗 CPU。transform/opacity 仅触发 Composite。此时元素已经绘制成位图(Texture),GPU 只需要对位图进行变换,速度极快且不占用主线程。