CSS 动画的实现主要依赖于两大核心体系:Transition(过渡) 和 Animation(关键帧动画)。
简单来说,Transition 适合处理简单的"状态切换"(比如鼠标悬停时颜色平滑变化),而 Animation 则能实现复杂的、多步骤的自动动画(比如加载时的旋转图标、弹跳的小球)。
下面为你详细拆解它们的实现方式:
1. 基础过渡:Transition(过渡)
Transition 只能定义开始 和结束 两个状态,当元素的属性发生变化时(比如通过 :hover 触发),浏览器会自动补全中间的过渡过程。
它通常需要配合 4 个子属性使用:
- transition-property :要过渡的 CSS 属性(如
width,background-color,或all表示所有属性)。 - transition-duration :过渡持续的时间(如
0.5s)。 - transition-timing-function :过渡的速度曲线(如
ease,linear)。 - transition-delay:延迟多久后开始过渡。
实现示例(鼠标悬停盒子变宽):
css
.box {
width: 100px;
height: 100px;
background-color: red;
/* 当宽度发生变化时,在0.5秒内平滑过渡 */
transition: width 0.5s ease;
}
.box:hover {
width: 300px; /* 鼠标放上去,宽度平滑变为300px */
}
2. 核心动画:@keyframes + Animation(关键帧动画)
这是 CSS 动画最强大的部分。它由两部分组成:
@keyframes:相当于动画的"剧本",定义动画从 0% 到 100% 各个阶段的状态。animation属性:将"剧本"应用到元素上,并控制播放时长、次数、方向等。
实现步骤:
第一步:定义关键帧(剧本) 使用 from (0%) 和 to (100%),或者具体的百分比来定义中间状态。
css
@keyframes moveAndChange {
0% {
transform: translateX(0);
background-color: red;
}
50% {
transform: translateX(200px);
background-color: blue;
}
100% {
transform: translateX(0);
background-color: red;
}
}
第二步:将动画绑定到元素 animation 是一个简写属性,它包含了控制动画的 8 个核心子属性:
| 属性名 | 作用 | 常见取值 |
|---|---|---|
| animation-name | 绑定的关键帧名称 | 对应 @keyframes 后的名字 |
| animation-duration | 动画完成一次所需时间 | 1s, 500ms |
| animation-timing-function | 速度曲线(节奏感) | ease(默认), linear(匀速), ease-in-out |
| animation-delay | 延迟多久开始 | 0.5s |
| animation-iteration-count | 播放次数 | 1(默认), infinite(无限循环) |
| animation-direction | 播放方向 | normal(正向), alternate(来回交替) |
| animation-fill-mode | 动画结束后的状态 | forwards(保持最后一帧), backwards |
| animation-play-state | 播放/暂停 | running(默认), paused(暂停) |
应用示例:
css
.box {
width: 100px;
height: 100px;
/* 简写格式:名称 时长 速度曲线 延迟 次数 方向 填充模式 */
animation: moveAndChange 2s ease-in-out infinite alternate;
}
3. 性能优化与最佳实践
在实现 CSS 动画时,为了保证页面流畅不卡顿,有几点需要特别注意:
- 优先使用
transform和opacity: 改变元素的width,height,margin,top/left等属性会触发浏览器的重排(Reflow/Layout) ,非常消耗性能。而transform(位移、旋转、缩放)和opacity(透明度)通常只会触发合成(Compositing),可以交给 GPU 硬件加速,性能极高。 - 善用
will-change: 如果你预知某个元素马上要开始动画,可以给它加上will-change: transform;。这会提前告诉浏览器:"这个元素要变了,请提前为它创建独立的渲染层",从而让动画更丝滑。 - 避免过度复杂的动画: 动画的目的是提升用户体验,过多的动画反而会分散用户注意力。