文章目录
- [1. 过渡(transition)](#1. 过渡(transition))
-
- [1.1 过渡的触发](#1.1 过渡的触发)
- [1.2 transition 写在哪里?](#1.2 transition 写在哪里?)
- [1.3 过渡相关属性](#1.3 过渡相关属性)
-
- transition-property
- transition-duration
- transition-delay
- transition-timing-function
- [transition 复合属性](#transition 复合属性)
- [1.4 过渡体验示例](#1.4 过渡体验示例)
- [2. 动画(animation)](#2. 动画(animation))
-
- [2.1 什么是关键帧?](#2.1 什么是关键帧?)
- [2.2 动画的基本使用](#2.2 动画的基本使用)
- [2.3 动画相关属性](#2.3 动画相关属性)
-
- animation-name
- animation-duration
- animation-delay
- animation-timing-function
- animation-iteration-count
- animation-direction
- animation-fill-mode
- animation-play-state
- [animation 复合属性](#animation 复合属性)
- [2.4 动画体验示例](#2.4 动画体验示例)
- [3. 过渡与动画对比总结](#3. 过渡与动画对比总结)
1. 过渡(transition)
简单来说,过渡就是让元素从一种样式平滑地转变为另一种样式 。
CSS 的属性值默认是"啪"一下直接切换的,比如一个方块从红色变成蓝色,瞬间完成,没有任何中间状态。
一旦加上了 transition,这个变化就会像动画一样平滑地"过渡"过去,比如用 0.3 秒慢慢从红色变成蓝色。
1.1 过渡的触发
过渡发生的前提是:属性值发生了变化。
只要有属性值改变,并且在该元素上声明了 transition,浏览器就会自动对这次变化进行平滑过渡。
那属性值怎样才会变化呢?最常见的就是通过用户操作触发,例如:
- 鼠标悬停(
:hover) - 元素获得焦点(
:focus) - 元素被激活(
:active) - 通过 JavaScript 修改元素的类名或内联样式
有些人认为"只有伪类才能触发过渡",这其实是一种常见误解。伪类(
:hover、:focus等)只是最直观的触发方式,任何导致属性值变化的手段都可以触发过渡,包括用 JS 修改样式。
所以可以这样理解:
过渡 = 属性值变化 + transition 声明。没有属性变化,过渡就不会发生;没有 transition 声明,变化就是一瞬间完成。
1.2 transition 写在哪里?
我们需要把 transition 写在元素的基础样式 中。
"基础样式"就是元素在默认状态下的样式,比如未被 :hover、:active 等触发时的样子。如下是正确示例:
css
.button {
background-color: blue; /* 基础样式:背景蓝色 */
color: white; /* 基础样式:文字白色 */
transition: all 0.3s; /* 过渡写在基础样式里 */
}
/* 触发过渡的状态:这里是鼠标悬停 */
.button:hover {
background-color: red; /* 改变背景 */
color: black; /* 改变文字颜色 */
}
这样写可以保证过渡效果双向工作:
- 鼠标移入时,属性从基础值过渡到
:hover中的值; - 鼠标移出时,属性再从
:hover值平滑回到基础值。
如果只把 transition 写在 :hover 里:
- 移入时有过渡;
- 移出时属性会瞬间跳回原值,没有平滑过程,体验很不流畅。
1.3 过渡相关属性
transition-property
- 作用:指定哪些属性需要过渡。只有这里定义的属性(如宽、高、颜色等)才会以平滑过渡方式变化。
- 常用值 :
none:不过渡任何属性。all:过渡所有能过渡的属性。- 具体某个属性名,例如:
width、height,若有多个以逗号分隔。
不是所有 CSS 属性都能过渡。值为数字,或者值能转换为数字的属性 ,通常都支持过渡,否则不支持。
常见支持过渡的属性:颜色、长度值、百分比、
z-index、opacity、2D 变换属性、3D 变换属性、阴影。
transition-duration
- 作用:设置过渡的持续时间,即从一个状态过渡到另一个状态需要多久。
- 常用值 :
0:没有任何过渡时间 ------ 默认值。s或ms:秒或毫秒,如0.3s、300ms。
- 列表形式 :
- 如果想让所有属性都持续相同时间,就写一个值;
- 如果想让不同属性持续不同时间,可以写一个时间列表,与
transition-property一 一对应。
transition-delay
- 作用 :指定开始过渡的延迟时间,单位:
s或ms,默认值为0。 - 同样支持列表,与属性一 一对应。
transition-timing-function
- 作用:设置过渡的速度曲线,也就是变化过程的"节奏"。
- 常用值 :
ease:平滑过渡 ------ 默认值linear:线性过渡(匀速)ease-in:慢 → 快ease-out:快 → 慢ease-in-out:慢 → 快 → 慢step-start:等同于steps(1, start)step-end:等同于steps(1, end)steps(integer, [start|end]):步进函数。第一个参数为正整数,指定步数;第二个参数为start或end,决定每一步值变化的时间点,默认为end。cubic-bezier(number, number, number, number):自定义贝塞尔曲线。
在线制作贝塞尔曲线:https://cubic-bezier.com
steps() 函数详解:
- 步数(正整数):表示将动画分成几个"台阶"。例如步数为 3,函数值会分成 3 段阶梯状的恒定值。
- 变化时间点(
start或end) :决定每个台阶的"新值"是从这一步的开头生效,还是从末尾生效。默认是end。
示例:假设步数 = 3
steps(3, end)(默认)- 第 1 步:时间区间 [0, 1) → 值为 V1
- 第 2 步:时间区间 [1, 2) → 值为 V2
- 第 3 步:时间区间 [2, 3] → 值为 V3
解释:每一步的"新值"在这一步的末尾才出现。变化发生在每个整点时刻的右侧,前一步的值一直保持到这一步结束。
steps(3, start)- 第 1 步:时间区间 [0, 1] → 值为 V1
- 第 2 步:时间区间 (1, 2] → 值为 V2
- 第 3 步:时间区间 (2, 3] → 值为 V3
解释:每一步的"新值"在这一步的开头立即生效。变化发生在每个整点时刻的左侧,一到时间点就切换为新值。
简单记忆:
end就是等一步走完再切换,start是一步开始就立刻切换。
transition 复合属性
可以将上述所有子属性合并成一个 transition 声明。
规则:
- 如果只设置一个时间,它表示
duration; - 如果设置两个时间,第一个是
duration,第二个是delay; - 其余值(属性名、timing-function)无顺序要求。
示例:
css
transition: 1s 1s linear all;
/* 对应:duration=1s, delay=1s, timing-function=linear, property=all */
1.4 过渡体验示例
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>过渡</title>
<style>
.outer {
width: 777px;
background-color: pink;
}
.inter {
width: 111px;
height: 111px;
background-color: rgb(255, 76, 106);
transition-property: all;
transition-duration: 5s;
transition-delay: 2s;
}
.inter:hover {
background-color: rgb(92, 255, 171);
transform: translate(666px);
}
</style>
</head>
<body>
<div class="outer">
<div class="inter"></div>
</div>
</body>
</html>

效果:鼠标悬停后,方块会延迟 2 秒,然后用 5 秒平滑改变背景色并向右平移 666px;移开鼠标时同样平滑返回。
2. 动画(animation)
2.1 什么是关键帧?
不知道大家是否看过这样一段视频:画了好几页画,然后连续快速翻动,画中的人物就像动了起来。
一段动画,本质上就是在一段时间内连续播放若干张静态画面,每一张画面我们叫一"帧"。一定时间内连续快速播放若干个帧,就成了人眼中看到的动画。同样时间内,播放的帧数越多,画面看起来越流畅。
在构成一段动画的若干帧中,起到决定性作用的几帧,就叫做关键帧 。浏览器会自动计算关键帧之间的过渡画面。

2.2 动画的基本使用
与过渡不同,动画是主动展现的:不需要用户操作就可以自动运行,而且可以在多个关键帧之间精细控制。
过渡 vs 动画的初步对比:
- 过渡:被动触发,依赖属性变化(通常由操作触发),只有开始和结束两种状态,适合简单的效果切换。
- 动画:可以自动运行,可定义多个关键帧,适合复杂的、连续的动态效果。
第一步:定义关键帧(定义动画)
- 方式一:简单定义(from/to)
css
@keyframes 动画名 {
from {
/* 起始状态属性 */
}
to {
/* 结束状态属性 */
}
}
- 方式二:完整百分比定义
css
@keyframes 动画名 {
0% { /* ... */ }
20% { /* ... */ }
40% { /* ... */ }
60% { /* ... */ }
80% { /* ... */ }
100% { /* ... */ }
}
第二步:给元素应用动画
将定义好的关键帧通过以下属性应用到具体元素上。
2.3 动画相关属性
animation-name
- 作用 :指定元素要使用的动画(对应
@keyframes的名称)。
animation-duration
- 作用 :设置动画完成一个周期所需的时间。不设置时间则使用默认值
0s,不会有任何动画效果 ,元素会瞬间切换到最终状态(这和过渡不设置duration一样,直接跳变)。
animation-delay
- 作用 :设置动画开始前的延迟时间,单位
s或ms,默认0。
示例:
css
.box {
animation-name: testKey;
animation-duration: 5s;
animation-delay: 0.5s;
}
animation-timing-function
- 作用 :设置动画的速度曲线,与过渡中的
transition-timing-function用法完全相同。 - 常用值 :
ease:平滑 ------ 默认值linear:线性ease-in:慢 → 快ease-out:快 → 慢ease-in-out:慢 → 快 → 慢step-start:等同于steps(1, start)step-end:等同于steps(1, end)steps(integer, [start|end]):步进函数,(详细解释见过渡部分,两者完全相同)cubic-bezier(number, number, number, number):自定义贝塞尔曲线
animation-iteration-count
- 作用:指定动画的播放次数。
- 常用值 :
number:具体播放次数(如1、2、3...)infinite:无限循环
animation-direction
- 作用:指定动画的播放方向。
- 常用值 :
normal:正常方向(默认)reverse:反方向运行alternate:先正常运行,再反方向运行,并持续交替alternate-reverse:先反方向运行,再正方向运行,并持续交替
animation-fill-mode
- 作用:设置动画执行前后,元素如何应用样式(即动画之外的状态)。
- 常用值 :
none:默认值,动画前后都不保留动画中的样式forwards:动画结束后,元素保持最后一帧的样式backwards:在动画延迟期间,元素就应用第一帧的样式both:同时应用forwards和backwards的规则
示例:
css
.box {
width: 100px;
height: 100px;
background: blue;
transform: scale(1); /* 默认大小 */
animation-name: grow;
animation-duration: 2s;
animation-delay: 1s;
animation-fill-mode: both; /* 试试换成 none / backwards / forwards */
}
@keyframes grow {
from {
transform: scale(0.5); /* 第一帧:缩小 */
}
to {
transform: scale(1.5); /* 最后一帧:放大(与默认 scale(1) 不同) */
}
}
-
none:延迟期保持 scale(1),动画结束跳回 scale(1)。
-
backwards:延迟期立即变为 scale(0.5),动画结束跳回 scale(1)。
-
forwards:延迟期保持 scale(1),动画结束后保持 scale(1.5)。
-
both:延迟期立即变为 scale(0.5),动画结束后保持 scale(1.5)。
animation-play-state
- 作用:控制动画的播放状态。
- 常用值 :
running:播放(默认)paused:暂停
注意 :
animation-play-state一般不写在复合属性里,而是单独使用,便于通过伪类或 JavaScript 动态控制播放/暂停。
animation 复合属性
和过渡类似,也可以把所有动画子属性合并成一个 animation 声明。
规则:
- 只设置一个时间,表示
duration; - 设置两个时间,第一个是
duration,第二个是delay; - 其他值无顺序要求。
示例:
css
.inner {
animation: change 3s 0.5s linear 2 alternate-reverse forwards;
}
2.4 动画体验示例
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动画</title>
<style>
.outer {
width: 777px;
background-color: pink;
}
.inter {
width: 111px;
height: 111px;
border-radius: 50%;
background-color: rgb(255, 76, 106);
animation-name: change;
animation-duration: 5s;
animation-direction: alternate;
}
@keyframes change {
from {}
to {
background-color: rgb(92, 255, 171);
transform: translate(666px);
}
}
</style>
</head>
<body>
<div class="outer">
<div class="inter"></div>
</div>
</body>
</html>

这个例子中,圆形元素会自动开始动画。
3. 过渡与动画对比总结
| 特性 | 过渡(transition) | 动画(animation) |
|---|---|---|
| 触发方式 | 需要属性值发生变化(通常由 :hover、JS 等触发) |
可自动运行,也可通过类名控制 |
| 状态定义 | 只有起始和结束两个状态(隐式) | 通过 @keyframes 定义多个关键帧(0%~100%) |
| 循环播放 | 不能自动循环,需反复触发 | 可设置 animation-iteration-count,支持无限循环 |
| 播放方向 | 无反向控制 | 支持 normal、reverse、alternate 等 |
| 播放/暂停 | 无法暂停(只能在触发后等待完成) | 可通过 animation-play-state 控制 |
| 结束状态 | 默认回到初始值 | 通过 animation-fill-mode 控制是否保持结束状态 |
| 适用场景 | 简单的悬停、聚焦等状态切换 | 复杂的动画序列、循环动画、自动演示 |
以上为个人学习总结,旨在梳理个人理解。如有疏漏或不当之处,欢迎指正与交流。