文章目录

CSS 动画:transition 与 @keyframes

发布于 2026-04-06 07:30:39 · 浏览 16 次 · 评论 0 条

CSS 动画:transition 与 @keyframes

CSS 动画是前端开发中最常用的交互手段之一。它能让页面元素动起来,提升用户体验。CSS 提供了两种主要的动画实现方式:transition@keyframes。理解它们的区别和使用场景,是掌握 CSS 动画的第一步。


transition:简单的状态过渡

transition 适用于两个状态之间的平滑过渡。当你改变元素的某个属性值时,transition 会让这个变化在指定时间内完成,而不是瞬间跳变。

核心属性

transition 是四个属性的简写形式:

属性 作用
transition-property 指定要动画的CSS属性
transition-duration 动画持续的时间
transition-timing-function 动画的速度曲线
transition-delay 动画开始前的延迟时间

基本用法

.box {
  width: 100px;
  height: 100px;
  background: #3498db;
  transition: all 0.3s ease;
}

.box:hover {
  width: 150px;
  background: #e74c3c;
}

这段代码的含义是:当鼠标悬停在 .box 上时,宽度和背景色会在 0.3 秒内平滑过渡。ease 是默认的速度曲线,表示开始和结束时较慢,中间较快。

单独设置每个属性

.box {
  transition-property: width, background-color;
  transition-duration: 0.5s, 0.3s;
  transition-timing-function: ease-in-out, linear;
  transition-delay: 0s, 0.2s;
}

这里宽度变化需要 0.5 秒,背景色变化需要 0.3 秒 且延迟 0.2 秒 开始。分别设置可以让不同属性的动画节奏更精细。

常见速度曲线

关键字 效果
ease 默认,慢-快-慢
linear 匀速运动
ease-in 慢慢开始,突然结束
ease-out 突然开始,慢慢结束
ease-in-out 慢-快-慢(比 ease 更明显)

你也可以使用 cubic-bezier() 自定义速度曲线:

.box {
  transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

这个贝塞尔曲线会产生"回弹"效果,元素到达目标位置后会轻微超出再弹回。


@keyframes:复杂的动画序列

transition 只能处理两个状态之间的变化,而 @keyframes 可以定义多个关键帧,实现复杂的动画序列。比如淡入淡出、无限循环、复杂变形等效果。

基本语法

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.element {
  animation: fadeIn 1s ease-in-out;
}

@keyframes 后跟动画名称(大括号内是动画定义),from 表示起始状态(等同于 0%),to 表示结束状态(等同于 100%)。

使用百分比定义多阶段动画

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

这个弹跳动画包含四个关键帧:起跳、最高点、回落、落地。百分比表示动画进行到某个阶段时应该处于的状态。

动画属性详解

animation 是多个属性的简写:

属性 默认值 说明
animation-name none 动画名称
animation-duration 0s 动画时长
animation-timing-function ease 速度曲线
animation-delay 0s 延迟时间
animation-iteration-count 1 播放次数(infinite 表示无限)
animation-direction normal 播放方向
animation-fill-mode none 动画前后的状态保持
animation-play-state running 播放或暂停

实用示例

无限旋转加载动画:

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

.loading {
  animation: spin 1.5s linear infinite;
}

linear 保证旋转速度均匀,infinite 让动画一直循环。

悬停时播放的脉冲效果:

@keyframes pulse {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.7);
  }
  70% {
    transform: scale(1.1);
    box-shadow: 0 0 0 15px rgba(52, 152, 219, 0);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
  }
}

.button:hover {
  animation: pulse 1s infinite;
}

控制动画方向

animation-direction 有四个可选值:

效果
normal 正向播放,每次都从 0% 到 100%
reverse 反向播放,从 100% 到 0%
alternate 奇数次正向,偶数次反向(适合呼吸效果)
alternate-reverse 奇数次反向,偶数次正向
.breathing {
  animation: breathe 3s ease-in-out infinite alternate;
}

transition 与 @keyframes 的核心区别

特性 transition @keyframes
触发方式 状态变化(hover、class切换等) 加载即开始或手动控制
关键帧数量 两个(起始、结束) 任意数量(0% 到 100%)
循环控制 不支持 支持 infinite 无限循环
复杂动画 无法实现 可以实现复杂序列
性能开销 较小 相对较大

选择建议:

  • 简单的状态过渡(如按钮悬停、颜色变化)用 transition
  • 复杂的动画序列(如加载动画、复杂特效)用 @keyframes

性能优化技巧

CSS 动画的性能主要取决于动画属性的选择。浏览器的合成层处理动画的效率最高,而触发布局重排的属性开销很大。

推荐动画属性

以下属性由合成器处理,性能最佳:

  • transform(位移、缩放、旋转、倾斜)
  • opacity(透明度)
  • filter(滤镜,部分浏览器)

避免动画的属性

以下属性会触发布局重排,性能较差:

  • widthheight
  • marginpadding
  • topleftrightbottom
  • border-width

will-change 优化

对于复杂动画,可以提前通知浏览器进行优化:

.box {
  will-change: transform;
}

但不要滥用,只在确实需要时才添加,否则会导致内存占用过高。


实用代码片段库

淡入效果

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in {
  animation: fadeIn 0.5s ease-out forwards;
}

forwards 会保持动画结束时的状态。

打字机效果

@keyframes type {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

.typewriter {
  overflow: hidden;
  white-space: nowrap;
  border-right: 2px solid #333;
  animation: type 2s steps(30) forwards;
}

steps(30) 让动画按 30 步完成,产生逐字显示的效果。

卡片悬停 3D 翻转

.card {
  perspective: 1000px;
}

.card-inner {
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

.card:hover .card-inner {
  transform: rotateY(180deg);
}

.card-front,
.card-back {
  backface-visibility: hidden;
}

.card-back {
  transform: rotateY(180deg);
}

perspective 设置透视效果,preserve-3d 保持 3D 空间,backface-visibility 隐藏背面。


常见问题解决

动画不执行? 检查是否设置了 animation-duration,默认值为 0s 会导致动画不播放。

动画结束后恢复原状? 使用 animation-fill-mode: forwards 保持结束状态,或 both 保持起始和结束状态。

transition 不生效? 确保触发状态的选择器 specificity 高于默认状态,比如使用 :hover 而不是添加新 class。

动画卡顿? 尽量只动画 transformopacity 属性,避免触发布局重排的属性。


总结

transition 是处理两个状态之间平滑过渡的最佳选择,语法简单,性能优秀。keyframes 则适合创建复杂的动画序列,支持多阶段控制、无限循环和精确的状态管理。实际开发中,根据动画的复杂程度选择合适的方式,并注意性能优化,就能做出流畅的页面动效。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文