尧图网站设计 尧图网站设计YAOTU DESIGN
TUTORIAL · ANIMATE

CSS 动画入门

transition、animation、keyframes——三种动效武器,让网页从静止变生动,又不喧宾夺主。

CSS 动画入门教程
难度 · 入门 时长 · 约 15 分钟 更新 · 2026-07-15

CSS 动画入门:transition、animation 与 transform

作者 · 尧图设计编辑部 发布 · 2026-07-15 阅读 · 1.4k

静态页面看久了会"死",加一点动效立刻就活。但动效是个危险品:用得好是点睛之笔,用过头就是花式打扰。CSS 提供了三件武器——transition、animation、transform,掌握它们的分工,就能做出"刚好够"的动效。

这篇我们一件件讲清楚:transition 处理状态切换、animation 做复杂循环、transform 负责变形位移,最后聊性能和分寸感。学完你不会做出炫技的动画,但能让页面在每个交互节点上都"跟手"。

一、transition:状态切换的平滑过渡

transition 是最常用的动效工具。它管的是"从一个状态到另一个状态的过渡"——比如鼠标悬停时颜色变深、按钮按下时缩放。你只需要声明"哪个属性、用多久、什么曲线",浏览器会自动补上中间帧。

.btn {
  background: #4A7C3A;
  transition: background 0.3s ease, transform 0.3s ease;
}

.btn:hover {
  background: #3a6b2c;
  transform: translateY(-2px); /* 悬停轻微上浮 */
}

transition 的关键不在时长,而在缓动曲线。ease 是默认值,开头慢中间快结尾慢,适合大多数交互。但如果你想要更有"个性"的动效,就要用 cubic-bezier 自己调曲线。

/* 自定义贝塞尔曲线:先快后慢,有"落定感" */
.card {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.card:hover {
  transform: scale(1.03);
}

上面这个 cubic-bezier 的第二个值超过 1,会产生"回弹"效果——元素冲过目标位置再弹回来,比平铺直叙的 ease 有灵气得多。这个技巧在做卡片悬停、按钮点击时特别好用。

提示:transition 只对可计算的中间值有效。display: none 到 block 没法过渡,height: auto 也不行。遇到这类情况,要用 opacity 或 max-height 变通处理。

二、animation 与 keyframes:复杂的循环动画

transition 只能在两个状态间过渡,要做"持续运转"或"多步骤"的动画,就得用 animation 配合 keyframes。keyframes 定义关键帧,animation 负责调度——播放几次、往复还是单向、暂停还是运行。

/* 定义关键帧:从透明淡入并上移 */
@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 应用动画:进入页面时淡入上浮 */
.reveal {
  animation: fadeUp 0.6s ease both;
}

animation 的几个常用属性值得记一下:iteration-count 控制播放次数(infinite 是无限循环),alternate 让动画往复来回(奇数次正向、偶数次反向),animation-fill-mode 决定动画结束前后保持哪一帧。

/* 加载指示器:无限旋转 */
@keyframes spin {
  to { transform: rotate(360deg); }
}

.loader {
  animation: spin 1s linear infinite;
}

/* 呼吸效果:往复缩放 */
@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

.dot {
  animation: breathe 2s ease-in-out infinite alternate;
}
提示:keyframes 用百分比(0%、50%、100%)能定义多段动画,比 from/to 两段更灵活。呼吸、脉冲这类需要中间停顿的效果,都得靠百分比来写。

三、transform:变形三件套 translate/scale/rotate

transform 是动效的"肌肉",几乎所有位移、缩放、旋转都靠它。它最大的优点是不触发重排——元素变形时不影响周围布局,浏览器只需在合成层上重新绘制,性能远好于改 top、left、width。

/* 位移:从原位置偏移,不影响布局 */
.float-up {
  transform: translateY(-10px);
}

/* 缩放:以中心为原点放大 */
.zoom-in {
  transform: scale(1.1);
}

/* 旋转:顺时针转 90 度 */
.turn {
  transform: rotate(90deg);
}

/* 组合:位移 + 缩放一起用 */
.card:hover {
  transform: translateY(-4px) scale(1.02);
}

多个 transform 可以连写,按顺序执行。组合时注意顺序——先旋转再平移,和先平移再旋转,效果完全不同。一般遵循"先缩放旋转、再位移"的顺序,符合直觉。

易错点:transform 的原点默认是元素中心。想做"从左上角展开"的效果,要用 transform-origin: top left 改原点,否则会从中间向四周扩散。

四、性能优化:让动画不卡顿

动效一多就容易卡,尤其在低端机上。卡顿的根源通常是触发了重排或重绘。重排是元素位置变了,浏览器要重新计算整个布局;重绘是外观变了,要重新绘制像素。两者都耗性能,重排更甚。

所以动画要尽量只动两个属性:transform 和 opacity。它们在合成层处理,不触发布局计算。相反,改 top、left、width、height、margin 都会引发重排,能避就避。

/* 差:改 top 触发重排,滚动时会卡 */
.bad {
  position: absolute;
  top: 0;
  transition: top 0.3s;
}
.bad.scroll { top: 20px; }

/* 好:用 transform 位移,只动合成层 */
.good {
  transform: translateY(0);
  transition: transform 0.3s;
}
.good.scroll { transform: translateY(20px); }

遇到复杂动画还可以用 will-change 提前告知浏览器"这个元素要变了",让它提前创建合成层。但别滥用,每个 will-change 都占内存,铺满全站反而拖慢。

/* 仅对确实会动的元素声明 */
.carousel-track {
  will-change: transform;
}

五、动效的适度原则

技术讲完了,最后回到分寸感。动效存在的意义是"引导注意力"和"提供反馈",不是炫技。几条原则值得刻在脑子里:

  • 短就是好:交互反馈动效控制在 200-400ms,超过 500ms 用户会觉得"迟钝"。
  • 有原因才动:悬停、点击、加载这些有触发才动,别让页面自己一直闪。
  • 尊重偏好:用 prefers-reduced-motion 媒体查询,给关闭动效偏好的用户一个静态版本。
/* 照顾不喜欢动效的用户 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
提示:判断动效该不该加,问自己一句"去掉它,用户会困惑吗"。会困惑,就加;只是"好看",就忍住。克制比堆砌更见功力。

三件武器讲完了。transition 管过渡、animation 管循环、transform 管变形,再配上性能意识和对"度"的把握,你就能做出既生动又不打扰的页面。这是基础教程的最后一课,接下来可以回到教程列表,挑感兴趣的方向继续深入。