Skip to content

CSS3之animation动画

CSS3 animation 动画 是前端开发中比 transition 更强大的动画机制。 如果说 transition 是“从A到B的简单过渡”,那么 animation 就是“可以控制整个过程的多阶段动画”。

我们来系统讲清楚 👇

🎬 一、animation 是什么?

CSS3 animation 允许通过关键帧(@keyframes 定义一系列样式变化, 浏览器会在这些关键帧之间自动计算中间帧,从而实现平滑动画。

✅ 简单理解: transition 只能从 状态 A → 状态 B, 而 animation 可以定义 A → B → C → D … 多阶段动画。

🧩 二、基本语法

1️⃣ 定义动画(@keyframes)

css
@keyframes 动画名称 {
  0%   { /* 起始状态 */ }
  50%  { /* 中间状态 */ }
  100% { /* 结束状态 */ }
}

2️⃣ 使用动画(animation 属性)

css
selector {
  animation: 动画名称 持续时间 速度曲线 延迟 次数 方向 填充模式 播放状态;
}

🧱 三、基础示例

html
<div class="box"></div>
css
.box {
  width: 100px;
  height: 100px;
  background: #42b983;
  animation: move 2s ease-in-out infinite alternate;
}

@keyframes move {
  from { transform: translateX(0); }
  to { transform: translateX(200px); }
}

效果: 盒子左右来回移动,永远循环。

🧠 四、animation 的八个属性

属性作用示例
animation-name动画名称(与 @keyframes 对应)move
animation-duration持续时间2s500ms
animation-timing-function速度曲线easelinearease-in-out
animation-delay延迟时间1s
animation-iteration-count播放次数infinite / 1 / 3
animation-direction播放方向normal / reverse / alternate / alternate-reverse
animation-fill-mode动画结束后的状态none / forwards / backwards / both
animation-play-state控制播放或暂停running / paused

🔹 示例:完整写法

css
.box {
  animation: move 3s linear 1s 2 alternate forwards;
}

等价于 👇

css
.box {
  animation-name: move;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-delay: 1s;
  animation-iteration-count: 2;
  animation-direction: alternate;
  animation-fill-mode: forwards;
}

🌀 五、关键帧定义方式

✅ 百分比写法(推荐)

css
@keyframes move {
  0% { transform: translateX(0); }
  50% { transform: translateX(150px); background: orange; }
  100% { transform: translateX(300px); background: red; }
}

✅ from / to 简写

css
@keyframes move {
  from { opacity: 0; }
  to { opacity: 1; }
}

⚙️ 六、动画方向详解(animation-direction

说明举例
normal正向播放(默认)0% → 100%
reverse反向播放100% → 0%
alternate正向 → 反向交替来回运动
alternate-reverse反向 → 正向交替来回运动(从终点开始)

🧭 七、动画结束状态(animation-fill-mode

说明效果
none动画结束后回到初始状态默认
forwards停留在结束帧状态常用于加载完成后保持最终样式
backwards动画开始前应用初始帧结合 delay 使用
both同时应用 forwards + backwards进入和退出都生效

💡 八、动画控制(animation-play-state

css
.box:hover {
  animation-play-state: paused; /* 鼠标悬停暂停 */
}

🎨 九、多个动画同时执行

css
animation:
  move 2s linear infinite,
  fade 3s ease-in-out 1s infinite alternate;

📌 多个动画之间用逗号分隔。

🧰 十、常见动画案例

✅ 1. 淡入淡出(fade in/out)

css
@keyframes fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
.fade-in {
  animation: fade 1s ease-in forwards;
}

✅ 2. 弹跳动画(bounce)

css
@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-30px); }
}
.ball {
  animation: bounce 0.6s ease infinite;
}

✅ 3. 旋转动画(rotate)

css
@keyframes rotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.spin {
  animation: rotate 1.5s linear infinite;
}

⚡ 十一、性能优化建议

建议原因
✅ 使用 transformopacity 动画不会触发布局回流(高性能)
❌ 避免动画 width / top / left会触发布局(慢)
✅ 使用 will-change 提前优化通知浏览器提前准备动画层
✅ 控制动画次数避免长时间占用 GPU

示例:

css
.element {
  will-change: transform, opacity;
}

⚖️ 十二、与 transition 对比总结

对比项transitionanimation
触发方式状态变化(如 hover)可自动播放
可控性只能定义开始和结束可定义多个关键帧
重复播放不支持支持循环播放
延迟与暂停可延迟但不能暂停可延迟、暂停、控制播放
应用场景简单过渡复杂连续动画

🧭 十三、结构化总结(思维导图版)

CSS3 Animation(动画)
 ├── 定义:基于关键帧的多阶段动画
 ├── 语法
 │   ├── @keyframes 动画名 { 0%~100% 样式 }
 │   └── animation: name duration timing delay count direction fill state;
 ├── 八大属性
 │   ├── animation-name
 │   ├── animation-duration
 │   ├── animation-timing-function
 │   ├── animation-delay
 │   ├── animation-iteration-count
 │   ├── animation-direction
 │   ├── animation-fill-mode
 │   └── animation-play-state
 ├── 关键帧写法
 │   ├── 百分比写法
 │   └── from/to 简写
 ├── 常见方向
 │   ├── normal / reverse / alternate / alternate-reverse
 ├── 应用场景
 │   ├── 淡入淡出
 │   ├── 弹跳
 │   ├── 旋转
 │   └── 进场/出场动效
 ├── 优化建议
 │   ├── transform / opacity 优先
 │   ├── will-change 提前优化
 │   └── 避免 layout 属性动画
 └── 与 transition 对比
     ├── transition:简单状态过渡
     └── animation:复杂可控动画

可用F12开发者工具查看元素及样式,可打开codepen在线编辑代码。

::: demo [vanilla]

html
<html>
  <div class="animationBox">
    <div class="rotate">旋转动画1</div>
    <div class="play">
      <div class="img">旋转动画2</div>
      <span><p class="p2"></p></span>
      <span><p></p></span>
      <span><p></p></span>
      <span><p class="p2"></p></span>
    </div>
    <div class="elasticity">弹性动画</div>
    <div class="elasticity2">曲线弹性</div>
  </div>
</html>

<style>
  .animationBox{overflow: hidden;}
  .animationBox>div{
    width: 100px;height: 100px;background: #eee;border-radius: 50%;text-align: center;line-height: 100px;margin: 30px;float:left;
  }
  .rotate{
    animation: rotate 5s linear infinite
  }
  .rotate:hover{ animation-play-state: paused}
  @keyframes rotate {
    0%{transform: rotate(0);}
  100%{transform: rotate(360deg);}
  }
  .animationBox>.play {
    position: relative;
    margin: 50px 30px;
    background:none;
  }
  .play .img{
    position: absolute;
    top: 0;
    left:0;
    z-index: 1;
    width: 100px;height: 100px; background: #eee;
    border-radius: 50%;

    animation: rotate 5s linear infinite
  }
  .play span {
    position: absolute;
    top: 1px;
    left:1px;
    z-index: 0;
    display: block;
    width: 96px;
    height: 96px;
    border: 1px solid #999;
    border-radius: 50%;
  }
  .play span p{display: block;width: 4px;height: 4px;background: #000;margin: -2px 0 0 50%;border-radius: 50%;opacity: 0.5;}
  .play span .p2{margin: 50% 0 0 -2px;}
  .play span{
    animation: wave 5s linear infinite
  }
  .play>span:nth-child(3){
    /* 延迟时间 */
    animation-delay:1s; 
  }
  .play>span:nth-child(4){
    animation-delay:2.2s;
  }
  .play>span:nth-child(5){
    animation-delay:3.8s;
  }
  
  @keyframes wave {
    0%
    {
      transform:scale(1) rotate(360deg);
      opacity: 0.8;
    }
  100%
    {
      transform:scale(1.8) rotate(0deg);
      opacity: 0;
    }
  }

  .elasticity{
    /* 参数说明
      动画名称 花费时间 贝塞尔曲线 延迟开始时间 播放次数n|infinite  是否反向播放动画
    */
    animation: elasticity 1s linear 2s infinite
  }
  
  @keyframes elasticity{
    0%{
      transform: scale(0);
    }
    60%{
      transform: scale(1.1);
    }
    90%{
      transform: scale(1);
    }
  }
  

  .elasticity2{
    /**
    贝塞尔曲线 cubic-bezier(x1,y1,x2,y2)

    通过调整贝塞尔曲线可以设置出多种动画效果,比如反弹效果等
    X轴的范围是0~1,Y轴的取值没有规定,但是也不宜过大
    直线:linear,即cubic-bezier(0,0,1,1)

    贝塞尔曲线在线工具:https://cubic-bezier.com/#.17,.67,.83,.67
      */
    animation: elasticity2 1s cubic-bezier(.39,.62,.74,1.39) 2s infinite
  }
  @keyframes elasticity2{
    0%{
      transform: scale(0);
    }
    90%{
      transform: scale(1);
    }
  }
</style>

:::

贝塞尔曲线 cubic-bezier(x1,y1,x2,y2)

通过调整贝塞尔曲线可以设置出多种动画效果,比如反弹效果等 X轴的范围是0~1,Y轴的取值没有规定,但是也不宜过大。 如:直线linear,即cubic-bezier(0,0,1,1)

贝塞尔曲线在线工具:https://cubic-bezier.com/#.17,.67,.83,.67

参考:https://www.w3school.com.cn/css3/index.asp