六维教程

CSS 动画入门

上一篇的过渡需要人为触发,鼠标悬停或者聚焦。但有些动效希望自动播放,比如加载转圈、提示弹跳、广告轮播。这就轮到 CSS 动画登场。它不需要触发,元素一渲染就开始动,而且支持多段变化,比过渡灵活得多。

关键帧,动画的剧本

动画首先要写剧本,告诉浏览器每一段时间元素是什么状态。这个剧本叫 @keyframes。最简单的写法用 from 和 to:

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

更复杂的多段动画用百分比,每一行是一段关键帧:

@keyframes bounce {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-30px); }
  100% { transform: translateY(0); }
}

@keyframes 后面跟的名字可以自己起,比如上面的 fade-in 和 bounce。关键帧里写的都是正常 CSS 属性,动画属性写在应用动画的那个元素上。

animation 属性全家桶

animation 有八个子属性,逐个看:

子属性 作用 注意事项
animation-name 指定用哪个关键帧 必须和 @keyframes 名字一致
animation-duration 一轮动画时长 必填,不写不播
animation-timing-function 速度曲线 多段动画每段可单独设置
animation-delay 延迟多久开始 负值可以让动画从中间开始
animation-iteration-count 播放次数 infinite 表示无限循环
animation-direction 播放方向 alternate 实现往复效果
animation-fill-mode 播放前后的状态 forwards 保持终点
animation-play-state 播放或暂停 常用 JS 控制暂停

通常用简写一行搞定:

.ball {
  animation: bounce 1s ease-in-out infinite;
}

顺序是名字、时长、速度曲线、次数。上面这行让小球永远上下弹跳。

fill-mode 干什么的

新手最容易忽略 fill-mode。它控制动画播放前后元素的状态。默认情况下,动画播完元素回到初始状态,还没开始时保持原样。有时想要”播完停在终点”,就用 forwards:

.box {
  animation: fade-in 1s forwards;  /* 播完保持透明度 1 的状态 */
}

反过来,backwards 是把第一帧状态提前应用,在延迟期间元素就处于起点状态。还有 both 是两者都要。做”永久停在终点”的效果时,forwards 几乎是必写的。

direction,往复运动

动画想来回摆,用 alternate。它让动画正着播一遍,反着播一遍,自动来回:

.ball {
  animation: bounce 0.8s ease-in-out infinite alternate;
}

配合 infinite,小球就是永远上下弹跳,比从 0% 到 100% 硬写循环自然得多。

过渡还是动画

两者都是动效,怎么选,一个原则就够了。简单状态变化用过渡,复杂多段或者自动播放用动画。

对比项 transition 过渡 animation 动画
触发方式 需要状态变化触发 可自动播放
关键帧 只有起点终点 支持多段
循环 不支持 支持 infinite
适用场景 hover、focus 反馈 加载动画、轮播

完整示例,加载转圈和弹跳球

做一个常见的加载旋转圈,再配一个弹跳小球:

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #ddd;
  border-top-color: #4a90d9;  /* 只让上边框有颜色,形成缺口 */
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.ball {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: #e74c3c;
  animation: bounce 0.8s ease-in-out infinite alternate;
}

@keyframes bounce {
  from { transform: translateY(0); }
  to   { transform: translateY(-40px); }
}

HTML 里放两个 div,class 分别叫 spinner 和 ball,页面一打开它们就自己动起来。

别忘了动效友好

动效虽好,但有些用户会头晕,甚至系统里开着”减少动态效果”选项。尊重他们的选择,用媒体查询里的兄弟属性 prefers-reduced-motion:

@media (prefers-reduced-motion: reduce) {
  .spinner,
  .ball {
    animation: none;
  }
}

一句媒体查询,关掉所有动画,用户友好程度立刻提升。

小结

动画的核心就两部分,@keyframes 写剧本,animation 播剧本。记住常用组合,无限循环加 alternate 做往复,加 forwards 保持终点。简单反馈用过渡,复杂动效用动画,最后别忘了照顾 prefers-reduced-motion 的用户。下一篇进入收官,把学过的所有知识串起来做完整页面。

上一篇
CSS 过渡与变换
下一篇
CSS 变量与 calc 函数