CSS 动画属性精讲:从基础到实战

CSS 动画是实现页面动态效果的核心技术之一,无需依赖 JavaScript,即可完成元素的位移、旋转、缩放、透明度变化等交互效果。其核心由两部分组成: @keyframes 关键帧定义 (规定动画 "做什么")和 动画属性(规定动画 "怎么播")。本文将从基础概念到实战案例,全面拆解 CSS 动画的核心知识点

一、核心基础:@keyframes 关键帧

@keyframes 是 CSS 动画的 "剧本",用于定义动画在不同时间点的状态(即 "关键帧")。浏览器会自动计算关键帧之间的过渡效果,实现平滑动画。

1. 语法规则

css 复制代码
/* 格式:@keyframes + 动画名称 { 关键帧列表 } */
@keyframes 动画名称 {
  /* 方式1:使用 from/to(对应 0%/100%,适合简单的"开始-结束"动画) */
  from { /* 动画开始时的样式 */ }
  to { /* 动画结束时的样式 */ }

  /* 方式2:使用百分比(适合多步骤动画,0%=开始,100%=结束,中间可加任意百分比) */
  0% { /* 初始状态 */ }
  50% { /* 动画中间状态 */ }
  100% { /* 结束状态 */ }
}

2. 关键特性

  • 动画名称 :自定义(如 slide-inrotate-spin),需与后续 animation-name 对应。
  • 关键帧百分比:可任意拆分(如 0%、20%、80%、100%),百分比顺序不影响执行(浏览器会按从小到大排序)。
  • 支持的样式 :并非所有 CSS 属性都能动画,仅支持 "可插值" 属性(如 transformopacitywidthbackground-color),不支持 display: none/blockvisibility(会跳变)

3. 基础示例:简单位移动画

css 复制代码
/* 定义关键帧:元素从左侧-100px 移到 0px */
@keyframes slideIn {
  from { transform: translateX(-100px); opacity: 0; } /* 开始:左移+透明 */
  to { transform: translateX(0); opacity: 1; } /* 结束:复位+不透明 */
}

/* 应用到元素 */
.box {
  width: 100px;
  height: 100px;
  background: #4285F4;
  /* 必须指定动画名称和时长(否则动画不生效) */
  animation-name: slideIn; /* 关联关键帧 */
  animation-duration: 1s; /* 动画总时长 */
}

二、动画核心属性:控制 "播放规则"

定义好 @keyframes 后,需通过 动画属性 控制播放逻辑(如时长、次数、延迟、速度曲线等)。CSS 提供了 8 个独立属性,以及 1 个简写属性 animation,下面逐一拆解。

1. 8 个独立动画属性详解

属性名 作用 取值范围 默认值
animation-name 关联 @keyframes 定义的动画名 自定义名称 / none(取消动画) none
animation-duration 动画总时长 时间值(如 1s500ms),不可为 0 0s(无动画)
animation-timing-function 动画速度曲线(缓动效果) 预定义值 / 贝塞尔曲线 / 阶梯函数 ease
animation-delay 动画延迟多久开始 时间值(正:延迟;负:提前开始) 0s
animation-iteration-count 动画重复次数 数字(如 3) / infinite(无限循环) 1
animation-direction 动画重复时的方向 normal/reverse/alternate/alternate-reverse normal
animation-fill-mode 动画结束 / 延迟时的元素状态 none/forwards/backwards/both none
animation-play-state 控制动画播放 / 暂停 running(播放) / paused(暂停) running

重点属性深度解析

以下是最容易混淆或高频使用的属性,需结合示例理解:

(1)animation-timing-function:速度曲线

控制动画在 "关键帧之间" 的过渡速度,决定动画的 "流畅感"。

取值 效果描述 适用场景
linear 匀速(速度不变) 机械运动(如时钟旋转)
ease 默认:慢→快→慢(中间加速) 通用交互(如按钮 hover)
ease-in 慢开始(加速) 入场动画(如元素从下往上)
ease-out 慢结束(减速) 退场动画(如元素消失)
ease-in-out 慢开始 + 慢结束(对称加速) 平滑往复动画(如弹窗切换)
cubic-bezier(n,n,n,n) 自定义贝塞尔曲线(4 个参数,0~1) 精细控制(如拟物动画)
steps(n, [start/end]) 阶梯动画(分 n 步完成,无过渡) 帧动画(如精灵图、数字跳动)

示例:阶梯动画(数字从 1 跳到 5)

css 复制代码
@keyframes count {
  0% { content: "1"; }
  25% { content: "2"; }
  50% { content: "3"; }
  75% { content: "4"; }
  100% { content: "5"; }
}
.count::after {
  content: "1";
  animation: count 2s steps(4) infinite; /* steps(4):分4步,每步0.5s */
}

(2)animation-fill-mode:动画前后状态

控制元素在 动画延迟开始前animation-delay 期间)和 动画结束后 的样式状态,解决 "动画结束后元素复位" 的问题。

取值 延迟前状态(delay 期间) 动画结束后状态 核心场景
none 元素默认样式 恢复元素默认样式 动画后无需保留状态
forwards 元素默认样式 保持 100% 关键帧样式 动画后固定在结束状态(如弹窗停留)
backwards 保持 0% 关键帧样式 恢复元素默认样式 延迟期间显示初始状态(如提前透明)
both 保持 0% 关键帧样式 保持 100% 关键帧样式 延迟 + 结束都需保留状态(如入场后固定)

示例:动画结束后不复位

css 复制代码
.box {
  animation: slideIn 1s forwards; /* 结束后保持 100% 状态(不透明+复位) */
}

(3)animation-direction:动画方向

控制动画重复时的播放方向,尤其适合 "往复动画"(如左右摇摆)。

取值 效果描述
normal 每次都从 0%→100%(正向)
reverse 每次都从 100%→0%(反向)
alternate 奇数次正向(0%→100%),偶数次反向(100%→0%)
alternate-reverse 奇数次反向(100%→0%),偶数次正向(0%→100%)

示例:左右摇摆动画

css 复制代码
@keyframes swing {
  0% { transform: translateX(-50px); }
  100% { transform: translateX(50px); }
}
.box {
  animation: swing 1s ease-in-out infinite alternate; /* 来回摇摆 */
}

2. animation 简写属性

为简化代码,可将 8 个独立属性合并为 animation 简写,顺序有严格要求(部分属性可省略):

语法顺序

css 复制代码
animation: 动画名 时长 速度曲线 延迟 重复次数 方向 填充模式 播放状态;
规则说明
  • 必须包含的两个属性:animation-nameanimation-duration(否则动画不生效)。
  • 可选属性:其他 6 个属性可按顺序省略(未写则用默认值)。
  • 延迟与时长的区别:先写时长,后写延迟(均为时间值,靠顺序区分)。

示例:简写对比

css 复制代码
/* 分开写 */
.box {
  animation-name: slideIn;
  animation-duration: 1s;
  animation-timing-function: ease;
  animation-delay: 0.5s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

/* 简写(效果完全一致) */
.box {
  animation: slideIn 1s ease 0.5s infinite alternate;
}

三、实战案例:3 个高频动画场景

理论结合实践,以下是项目中常用的动画案例,可直接复用。

案例 1:加载旋转动画(无限循环)

css 复制代码
/* 关键帧:360度旋转 */
@keyframes spin {
  to { transform: rotate(360deg); } /* 0% 可省略(默认元素初始状态) */
}

/* 加载图标样式 */
.loader {
  width: 40px;
  height: 40px;
  border: 4px solid #eee;
  border-top-color: #4285F4; /* 顶部边框变色,模拟旋转感 */
  border-radius: 50%; /* 圆形 */
  /* 动画:旋转 1s 匀速 无限循环 */
  animation: spin 1s linear infinite;
}

案例 2:hover 悬浮放大 + 阴影动画

css 复制代码
/* 关键帧:放大+加阴影 */
@keyframes hoverScale {
  to {
    transform: scale(1.05); /* 放大5% */
    box-shadow: 0 4px 20px rgba(0,0,0,0.1); /* 增加阴影 */
  }
}

/* 按钮样式 */
.btn {
  padding: 8px 16px;
  border: none;
  background: #4285F4;
  color: white;
  border-radius: 4px;
  transition: all 0.3s; /* 过渡(可选,与动画互补) */
  /* 初始:动画暂停;hover时播放 */
  animation: hoverScale 0.3s forwards paused;
}

/* hover 触发动画 */
.btn:hover {
  animation-play-state: running; /* 播放动画 */
}

案例 3:多步骤动画(位移 + 旋转 + 变色)

css 复制代码
/* 关键帧:3步动画 */
@keyframes multiStep {
  0% {
    transform: translateX(0) rotate(0);
    background: #4285F4;
  }
  50% {
    transform: translateX(200px) rotate(180deg);
    background: #EA4335;
  }
  100% {
    transform: translateX(400px) rotate(360deg);
    background: #34A853;
  }
}

.box {
  width: 100px;
  height: 100px;
  border-radius: 8px;
  /* 动画:3步动画 3s 缓动 延迟0.5s 播放1次 正向 结束后固定状态 */
  animation: multiStep 3s ease 0.5s 1 normal forwards;
}

四、常见问题与解决方案

新手使用 CSS 动画时,常遇到 "动画不生效" 或 "效果异常",以下是高频问题汇总:

问题现象 原因分析 解决方案
动画完全不播放 1. 未设置 animation-duration(默认 0s) 2. animation-name@keyframes 名称不匹配 1. 必须指定 duration(如 1s) 2. 检查名称拼写(区分大小写)
动画结束后立即复位 animation-fill-mode 未设置为 forwardsboth 添加 forwards(保持结束状态)
transform 动画无效果 元素未触发 "层叠上下文",或父元素有 overflow: hidden 1. 加 will-change: transformposition: relative 2. 检查父元素 overflow 设置
动画卡顿、掉帧 1. 使用了会触发重排的属性(如 widthmargin) 2. 动画元素过多 1. 优先用 transformopacity(浏览器优化好) 2. 加 will-change: transform 提前通知浏览器优化
延迟期间元素样式异常 animation-fill-mode 未设置为 backwardsboth 添加 backwards(延迟时显示 0% 状态)

五、性能优化技巧

CSS 动画虽轻量,但不合理使用会导致页面卡顿,尤其在移动端。以下是关键优化点:

  1. 优先使用 transformopacity
    浏览器对这两个属性的动画会开启 "合成层" 优化,避免触发页面重排(reflow)和重绘(repaint),仅需合成(composite),性能最优。
    ❌ 避免动画:widthheightmargintopleft(会触发重排)。
  2. 使用 will-change 提前优化
    告诉浏览器 "该元素即将动画",让浏览器提前分配资源,减少动画启动时的卡顿:
css 复制代码
.box {
  will-change: transform, opacity; /* 提前声明要动画的属性 */
}

⚠️ 注意:不要滥用 will-change(如给所有元素加),会占用额外内存。

3. 减少动画元素数量

同时动画的元素越多,性能压力越大,建议控制在 5 个以内(复杂场景需用 JS 节流 / 防抖)。

4. 避免过度使用 infinite 循环动画

无限循环动画会持续占用主线程,非必要时可通过 JS 控制播放 / 暂停(如滚动到视图时播放)。

六、兼容性说明

现代浏览器(Chrome、Firefox、Safari 10+、Edge)均支持标准 CSS 动画属性,无需前缀。但对于 Safari 9 及以下版本 ,需添加 -webkit- 前缀:

css 复制代码
/* 关键帧前缀 */
@-webkit-keyframes slideIn {
  from { -webkit-transform: translateX(-100px); }
  to { -webkit-transform: translateX(0); }
}

/* 属性前缀 */
.box {
  -webkit-animation-name: slideIn;
  -webkit-animation-duration: 1s;
  /* 简写前缀 */
  -webkit-animation: slideIn 1s ease;
}

可通过 caniuse 查看最新兼容性数据。

七、前端动画库

一、通用动画库(全能型)

1. GreenSock (GSAP)

  • 特点:业界公认的高性能动画库,支持 CSS、SVG、Canvas、WebGL 等几乎所有前端元素,可实现时间线控制、贝塞尔曲线、滚动触发等复杂逻辑。
  • 优势:性能极强(尤其在移动端),支持动画暂停 / 重播 / 反转,API 灵活,兼容性好(IE9+)。
  • 适用场景:复杂交互动画(如页面过渡、游戏动效、数据可视化动效)。

示例

js 复制代码
// 基础动画:元素从左移到右并淡入
gsap.to(".box", { 
  x: 300, 
  opacity: 1, 
  duration: 1, 
  ease: "power2.out" 
});

官网: greensock.com

2. Framer Motion

  • 特点:React 生态最流行的动画库,基于 React 组件设计,支持声明式动画,内置手势(拖拽、缩放)和物理动效。
  • 优势:与 React 无缝集成,API 简洁,支持动画组合和变体(Variants)复用。
  • 适用场景:React 项目的 UI 交互(如组件切换、列表动效、手势反馈)。

示例

js 复制代码
// React组件动画
import { motion } from "framer-motion";

const Box = () => (
  <motion.div
    initial={{ x: -100, opacity: 0 }}
    animate={{ x: 0, opacity: 1 }}
    transition={{ duration: 0.5 }}
  />
);

官网www.framer.com/motion

二、CSS 动画库(轻量基础)

1. Animate.css

  • 特点:最经典的 CSS 类动画库,提供预设的基础动画(如淡入、滑动、旋转),直接通过添加类名使用。
  • 优势:零配置、轻量(~70KB)、支持自定义(可通过工具生成子集)。
  • 适用场景:快速添加简单动效(如按钮 hover、元素入场)。

示例

html 复制代码
<!-- 直接添加类名 -->
<div class="animate__animated animate__bounce"> bounce动画 </div>

官网animate.style

2. AnimXYZ

  • 特点:基于 CSS 变量的动画库,支持通过类名动态组合动画参数(如方向、距离、时长),高度可定制。
  • 优势:无需写 CSS,通过 HTML 类名控制动画细节,适合快速迭代。

示例

html 复制代码
<!-- 向右移动20px,持续0.5s,缓入缓出 -->
<div class="xyz-in xyz-translate-x-20 xyz-duration-500 xyz-ease-in-out"></div>

官网animxyz.com

三、3D / 物理仿真动画库

1. Three.js

  • 特点:基于 WebGL 的 3D 动画库,可创建 3D 模型、场景、光照和相机,实现 3D 旋转、缩放、物理碰撞等效果。
  • 优势:功能全面,社区活跃,支持加载 3D 模型(如 GLB、OBJ)。
  • 适用场景:3D 可视化(如产品展示、数据 3D 图表、小游戏)。

官网threejs.org

2. Matter.js

  • 特点:2D 物理引擎库,支持重力、碰撞、摩擦、关节约束等物理效果,可模拟现实世界运动。
  • 优势:轻量(~100KB),API 简单,适合实现拖拽碰撞、堆叠等效果。
  • 适用场景:物理交互动效(如拖拽元素碰撞、物体掉落动画)。

官网: brm.io/matter-js

四、SVG/Canvas 动画库

1. Lottie

  • 特点:由 Airbnb 开发,支持将 AE(After Effects)动画导出为 JSON,通过前端解析播放,完美还原 AE 动效。
  • 优势:矢量动画(无损缩放),体积小,支持交互控制(暂停、反转)。
  • 适用场景:复杂矢量动画(如 LOGO 动效、引导页动画、图标动效)。

示例:

html 复制代码
<script src="lottie.js"></script>
<div id="animation-container"></div>
<script>
  lottie.loadAnimation({
    container: document.getElementById('animation-container'),
    path: 'animation.json', // AE导出的JSON
    loop: true,
    autoplay: true
  });
</script>

官网lottiefiles.com

2. Vivus

  • 特点:专注于 SVG 路径动画,模拟 "手绘" 效果(路径逐帧绘制)。
  • 优势:轻量(~15KB),支持自定义绘制速度、延迟、方向。
  • 适用场景:SVG 图标绘制动画、手写文字效果。

官网maxwellito.github.io/vivus

五、交互反馈动画库

1. TweenMax(GSAP 核心模块)

  • 特点:GSAP 的基础模块,专注于元素补间动画,支持时间线(Timeline)控制多个动画的顺序和叠加。
  • 优势:比原生 CSS 动画性能更好,尤其在复杂序列动画中。
  • 适用场景:需要精确控制时序的动画(如多元素分步入场)。

2. React Spring

  • 特点:基于物理弹簧模型的 React 动画库,动画效果更贴近自然(如弹性、惯性)。
  • 优势:声明式 API,适合模拟真实物理动效(如弹性缩放、惯性滑动)。

示例

js 复制代码
import { useSpring, animated } from 'react-spring';

const AnimatedDiv = () => {
  const props = useSpring({ 
    from: { opacity: 0 }, 
    to: { opacity: 1 },
    config: { tension: 100 } // 弹簧张力
  });
  return <animated.div style={props} />;
};

官网react-spring.dev

相关推荐
明天的明2 小时前
vue双向数据绑定失效
前端
bug_kada2 小时前
前端路由:深入理解History模式
前端·面试
Ticnix2 小时前
vue的draggable拖拽属性+Echarts实现可视化自定义数据看板
前端
XTransfer技术2 小时前
RN也有微前端框架了? Xtransfer的RN优化实践(一)多bundle架构
前端·react native
Mintopia2 小时前
Next 全栈之 API 测试:Supertest 与 MSW 双雄记 🥷⚔️
前端·javascript·next.js
泽泽爱旅行2 小时前
awk 语法解析-前端学习
linux·前端
鹏多多2 小时前
纯前端人脸识别利器:face-api.js手把手深入解析教学
前端·javascript·人工智能
无奈何杨3 小时前
CoolGuard增加枚举字段支持,条件编辑优化,展望指标取值不同
前端·后端
掘金安东尼3 小时前
工具过多:如何管理前端工具泛滥?
前端