目录
[1. @keyframes 关键帧](#1. @keyframes 关键帧)
[2. animation 属性](#2. animation 属性)
二、动画调速函数(animation-timing-function)
[1. 预设值](#1. 预设值)
[2. 贝塞尔曲线](#2. 贝塞尔曲线)
[3. 步进函数(steps())](#3. 步进函数(steps()))
[1. 暂停与恢复](#1. 暂停与恢复)
[2. JavaScript 控制](#2. JavaScript 控制)
[1. 淡入淡出效果](#1. 淡入淡出效果)
[2. 旋转加载图标](#2. 旋转加载图标)
[3. 弹跳效果](#3. 弹跳效果)
CSS 动画允许通过定义关键帧(
@keyframes
)和动画属性(animation
)实现复杂的动态效果,相比transition
更灵活,支持多阶段控制和循环播放。
一、核心概念与语法
在 CSS 中,以 @
开头的语法称为 At-Rules(规则声明),用于定义 CSS 的元数据、条件逻辑、外部资源引入等高级功能。
1. @keyframes
关键帧

-
作用:定义动画的中间状态。
-
语法:
css@keyframes 动画名称 { from { /* 初始状态 */ } to { /* 结束状态 */ } /* 或使用百分比 */ 0% { ... } 50% { ... } 100% { ... } }
-
示例:
css@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideAndRotate { 0% { transform: translateX(0) rotate(0); } 50% { transform: translateX(200px) rotate(180deg); } 100% { transform: translateX(0) rotate(360deg); } }
2. animation
属性


-
作用:将关键帧动画应用到元素。
-
子属性:
属性 作用 常用值 animation-name
指定关键帧名称 fadeIn
,slideAndRotate
animation-duration
动画持续时间 2s
,500ms
animation-timing-function
速度曲线 ease
(默认),linear
,ease-in-out
,cubic-bezier(0.4, 0, 0.2, 1)
animation-delay
动画延迟时间 1s
,0.5s
animation-iteration-count
播放次数 1
(默认),infinite
,3
animation-direction
播放方向 normal
(默认正向),reverse
(反向),alternate
(正反交替)animation-fill-mode
动画结束后的样式保留 none
(默认),forwards
(保持最后一帧),backwards
(应用第一帧)animation-play-state
控制播放状态 running
(默认),paused
(暂停) -
简写语法:
css.element { animation: name duration timing-function delay iteration-count direction fill-mode play-state; }
示例:
css.box { animation: fadeIn 2s ease-in-out 1s infinite alternate forwards; }
二、动画调速函数(animation-timing-function
)
1. 预设值
-
ease
:默认缓入缓出(先加速后减速)。 -
linear
:匀速。 -
ease-in
:缓入(逐渐加速)。 -
ease-out
:缓出(逐渐减速)。 -
ease-in-out
:缓入缓出。
2. 贝塞尔曲线
- 使用
cubic-bezier(x1, y1, x2, y2)
自定义速度曲线。
css
.box {
animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
3. 步进函数(steps()
)
-
将动画拆分为固定步数播放,适合帧动画。
css.box { animation-timing-function: steps(5, jump-start); /* 分 5 步跳跃播放 */ }
三、动画控制与交互
1. 暂停与恢复
-
通过
animation-play-state
控制:css.box:hover { animation-play-state: paused; /* 悬停时暂停动画 */ }
2. JavaScript 控制
-
动态添加/移除动画类:
cssconst box = document.querySelector('.box'); box.classList.add('fadeIn'); // 触发动画 box.style.animation = 'none'; // 停止动画
3.逐帧动画与精灵图

css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<link rel="stylesheet" href="./iconfont/iconfont.css">
<style>
.box {
margin: 100px auto;
width: 1000px;
}
.people {
width: 140px;
height: 140px;
background-image: url(./res/run.png);
animation:
run 1s steps(12) infinite,
move 4s linear infinite;
}
@keyframes run {
from {
background-position: 0 0;
}
to {
background-position: -1680px 0;
}
}
@keyframes move {
0% {
transform: translate(0) scaleX(1);
}
50% {
transform: translate(800px) scaleX(1);
}
50.1% {
transform: translate(800px) scaleX(-1);
}
100% {
transform: translate(0) scaleX(-1);
}
}
</style>
</head>
<body>
<div class="box">
<div class="people"></div>
</div>
</body>
</html>

四、性能优化
-
优先使用
transform
和opacity
- 这些属性由 GPU 加速,避免触发重排(如
width
、margin
)。
- 这些属性由 GPU 加速,避免触发重排(如
-
减少动画数量
- 同时运行过多动画可能导致页面卡顿。
-
使用
will-change
提示浏览器css.box { will-change: transform, opacity; /* 提前告知浏览器可能变化的属性 */ }
五、实际应用示例
1. 淡入淡出效果
css
@keyframes fadeInOut {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
.element {
animation: fadeInOut 3s ease-in-out infinite;
}
2. 旋转加载图标
css
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.loader {
animation: spin 1s linear infinite;
}
3. 弹跳效果
css
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-30px); }
}
.button {
animation: bounce 1s ease-in-out infinite;
}
六、兼容性与前缀
-
现代浏览器:无需前缀(Chrome 43+、Firefox 16+、Safari 9+)。
-
旧版浏览器 :需添加
-webkit-
前缀:css@-webkit-keyframes fadeIn { ... } .box { -webkit-animation: fadeIn 2s; }
示例:走马灯
css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<link rel="stylesheet" href="./iconfont/iconfont.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
a {
text-decoration: none;
color: #fff;
}
.box {
margin: 100px auto;
width: 300px;
height: 50px;
overflow: hidden;
}
.box ul {
display: flex;
animation: move 7s linear infinite;
}
.box:hover ul {
animation-play-state: paused;
}
@keyframes move {
from {
transform: translateX(0);
}
to {
transform: translateX(-700px);
}
}
.box img {
width: 100px;
}
</style>
</head>
<body>
<div class="box">
<ul>
<li><img src="./res/1.jpg" alt=""></li>
<li><img src="./res/2.jpg" alt=""></li>
<li><img src="./res/3.jpg" alt=""></li>
<li><img src="./res/4.jpg" alt=""></li>
<li><img src="./res/5.jpg" alt=""></li>
<li><img src="./res/6.jpg" alt=""></li>
<li><img src="./res/7.jpg" alt=""></li>
<!-- 填补显示区域的空白 -->
<li><img src="./res/1.jpg" alt=""></li>
<li><img src="./res/2.jpg" alt=""></li>
<li><img src="./res/3.jpg" alt=""></li>
</ul>
</div>
</body>
</html>

示例:全民出游季
css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<link rel="stylesheet" href="./iconfont/iconfont.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
a {
text-decoration: none;
color: #fff;
}
html {
height: 100%;
}
body {
height: 100%;
background: url(./res/images/f1_1.jpg) no-repeat center 0 / cover;
}
.cover {
width: 100%;
height: 100%;
position: relative;
}
.cover div {
position: absolute;
}
.title {
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
animation: show 1s;
}
@keyframes show {
0% {
transform: translate(-50%,-50%) scale(1);
}
20% {
transform: translate(-50%,-50%) scale(0.3);
}
50% {
transform: translate(-50%,-50%) scale(1.7);
}
80% {
transform: translate(-50%,-50%) scale(0.8);
}
100% {
transform: translate(-50%,-50%) scale(1);
}
}
.label {
bottom: 10%;
left: 50%;
transform: translate(-50%);
}
.label ul {
display: flex;
justify-content: space-between;
}
.label ul img {
width: 100px;
margin: 0 85px;
animation: bounce .8s ease-in infinite alternate;
}
.label ul li:nth-child(2) img {
animation: bounce .8s 0.3s ease-in infinite alternate;
}
.label ul li:nth-child(3) img {
animation: bounce .8s 0.6s ease-in infinite alternate;
}
.label ul li:nth-child(4) img {
animation: bounce .8s 0.9s ease-in infinite alternate;
}
@keyframes bounce {
from {
transform: translateY(0);
}
to {
transform: translateY(30px);
}
}
.cloud {
position: relative;
left: 50%;
}
.cloud img:nth-child(1) {
top: 20px;
margin-left: -200px;
}
.cloud img:nth-child(2) {
top: 100px;
margin-left: 400px;
}
.cloud img:nth-child(3) {
top: 180px;
margin-left: -500px;
}
.cloud img {
position: absolute;
animation: move 2s linear infinite alternate;
}
@keyframes move {
to {
transform: translate(-50px);
}
}
.lu {
top: 15%;
left: 60%;
}
.san {
top: 15%;
left: 25%;
animation: float 1.5s linear infinite alternate;
}
@keyframes float {
to {
transform: translateY(50px);
}
}
</style>
</head>
<body>
<div class="cover">
<div class="cloud">
<img src="./res/images/yun1.png" alt="">
<img src="./res/images/yun2.png" alt="">
<img src="./res/images/yun3.png" alt="">
</div>
<div class="lu"><img src="./res/images/lu.png" alt=""></div>
<div class="san"><img src="./res/images/san.png" alt=""></div>
<div class="label">
<ul>
<li><img src="./res/images/1.png" alt=""></li>
<li><img src="./res/images/2.png" alt=""></li>
<li><img src="./res/images/3.png" alt=""></li>
<li><img src="./res/images/4.png" alt=""></li>
</ul>
</div>
<div class="title"><img src="./res/images/font1.png" alt=""></div>
</div>
</body>
</html>
