目录
- 一、核心区别速览
- 二、transition(过渡动画)
- [2.1 一句话定义](#2.1 一句话定义)
- [2.2 语法](#2.2 语法)
- [2.3 运动曲线(timing-function)](#2.3 运动曲线(timing-function))
- [2.4 适用场景](#2.4 适用场景)
- [三、animation + @keyframes(关键帧动画)](#三、animation + @keyframes(关键帧动画))
- [3.1 一句话定义](#3.1 一句话定义)
- [3.2 两部分组成](#3.2 两部分组成)
- [3.3 关键属性详解](#3.3 关键属性详解)
- [3.4 适用场景](#3.4 适用场景)
- [四、transition vs animation 详细对比](#四、transition vs animation 详细对比)
- 五、实战示例
- 示例1:按钮悬停效果(transition)
- 示例2:骨架屏加载(animation)
- 示例3:通知消息入场/出场
- 六、面试高频问题
- [Q1:transition 和 animation 的区别?](#Q1:transition 和 animation 的区别?)
- [Q2:如何用 transition 实现循环动画?](#Q2:如何用 transition 实现循环动画?)
- [Q3:animation 的 fill-mode 有什么作用?](#Q3:animation 的 fill-mode 有什么作用?)
一、核心区别速览
| 对比维度 | transition | animation |
|---|---|---|
| 中文名 | 过渡动画 | 关键帧动画 |
| 定义方式 | 起点 → 终点 | 可定义多个关键帧(0% → 50% → 100%) |
| 触发条件 | ✅ 需要(hover、click、class变化) | ❌ 不需要(页面加载可自动执行) |
| 循环播放 | ❌ 不支持(需要JS配合) | ✅ 支持(infinite无限循环) |
| 中间状态 | 自动计算补间 | 可精确控制每一帧 |
| 适用场景 | 简单、一次性动画 | 复杂、连续、自动播放动画 |
二、transition(过渡动画)
2.1 一句话定义
让元素从一个样式状态,平滑过渡到另一个样式状态。
2.2 语法
css
/* 完整写法 */
transition: 属性名 时长 运动曲线 延迟时间;
/* 示例 */
.box {
width: 100px;
height: 100px;
background: red;
/* 所有属性变化都过渡,时长0.5秒,缓动曲线,不延迟 */
transition: all 0.5s ease 0s;
/* 或者分开写 */
transition-property: width, height; /* 要过渡的属性 */
transition-duration: 0.5s; /* 过渡时长 */
transition-timing-function: ease; /* 运动曲线 */
transition-delay: 0s; /* 延迟时间 */
}
.box:hover {
width: 200px;
height: 200px;
background: blue;
}
2.3 运动曲线(timing-function)
| 值 | 效果 | 说明 |
|---|---|---|
ease |
慢→快→慢 | 默认值,最自然 |
linear |
匀速 | 机械感 |
ease-in |
慢→快 | 加速 |
ease-out |
快→慢 | 减速 |
ease-in-out |
慢→快→慢 | 与ease类似但更平滑 |
cubic-bezier(n,n,n,n) |
自定义 | 贝塞尔曲线 |
css
/* 自定义贝塞尔曲线 */
.box {
transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* 可以做出弹簧效果 */
}
2.4 适用场景
css
/* 1. hover 按钮变色 */
.btn {
background: blue;
transition: background 0.3s ease;
}
.btn:hover {
background: red;
}
/* 2. 菜单展开/收起 */
.menu {
height: 0;
opacity: 0;
transition: all 0.3s ease;
}
.menu.open {
height: 200px;
opacity: 1;
}
/* 3. 卡片悬停放大 */
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-10px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
三、animation + @keyframes(关键帧动画)
3.1 一句话定义
自己定义多个关键状态,让元素自动按顺序播放的复杂动画。
3.2 两部分组成
css
/* 第1步:定义关键帧 */
@keyframes 动画名称 {
0% {
/* 起始样式 */
transform: translateX(0);
opacity: 0;
}
50% {
/* 中间样式 */
transform: translateX(50px);
opacity: 0.5;
}
100% {
/* 结束样式 */
transform: translateX(100px);
opacity: 1;
}
}
/* 第2步:应用动画 */
.box {
animation-name: 动画名称; /* 关键帧名称 */
animation-duration: 2s; /* 动画时长 */
animation-timing-function: ease; /* 运动曲线 */
animation-delay: 0s; /* 延迟时间 */
animation-iteration-count: 1; /* 播放次数(infinite无限) */
animation-direction: normal; /* 播放方向 */
animation-fill-mode: forwards; /* 动画结束后保持最后一帧 */
animation-play-state: running; /* 播放状态 */
}
/* 简写(推荐) */
/* animation: 名称 时长 曲线 延迟 次数 方向 填充模式; */
.box {
animation: slideIn 0.5s ease 0s 1 normal forwards;
}
3.3 关键属性详解
| 属性 | 可选值 | 说明 |
|---|---|---|
animation-name |
自定义名称 | 对应@keyframes的名称 |
animation-duration |
时间(s/ms) | 动画时长 |
animation-timing-function |
ease/linear/step等 | 运动曲线 |
animation-delay |
时间(s/ms) | 延迟多久开始 |
animation-iteration-count |
数字 / infinite | 播放次数 |
animation-direction |
normal / reverse / alternate | 播放方向 |
animation-fill-mode |
none / forwards / backwards | 结束后状态 |
animation-play-state |
running / paused | 播放/暂停 |
3.4 适用场景
css
/* 1. 加载动画(无限循环) */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.loader {
animation: spin 1s linear infinite;
}
/* 2. 入场动画(自动执行) */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.page-enter {
animation: fadeInUp 0.5s ease forwards;
}
/* 3. 复杂多阶段动画 */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-30px); }
70% { transform: translateY(-10px); }
}
.bounce {
animation: bounce 1s ease infinite;
}
/* 4. 呼吸灯效果 */
@keyframes pulse {
0% { opacity: 0.6; transform: scale(1); }
50% { opacity: 1; transform: scale(1.05); }
100% { opacity: 0.6; transform: scale(1); }
}
.pulse {
animation: pulse 2s ease infinite;
}
四、transition vs animation 详细对比
| 对比维度 | transition | animation |
|---|---|---|
| 触发方式 | 需要触发(hover/click/class) | 自动触发(页面加载即执行) |
| 关键帧 | 只有起点和终点 | 可定义多个关键帧(0%-100%) |
| 循环播放 | ❌ 不支持 | ✅ 支持(infinite) |
| 反向播放 | ❌ 需要重新触发 | ✅ 支持(alternate/reverse) |
| 暂停/播放 | ❌ 不支持 | ✅ 支持(animation-play-state) |
| 结束后状态 | 回到起点 | 可保持终点(forwards) |
| 代码量 | 少 | 多 |
| 控制精度 | 低 | 高 |
| 适用场景 | 简单交互动画 | 复杂连续动画 |
五、实战示例
示例1:按钮悬停效果(transition)
css
.btn {
padding: 10px 20px;
background: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
/* 多个属性分别设置过渡 */
transition:
background 0.3s ease,
transform 0.2s ease,
box-shadow 0.3s ease;
}
.btn:hover {
background: #2980b9;
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn:active {
transform: translateY(0);
}
示例2:骨架屏加载(animation)
css
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
.skeleton {
background: linear-gradient(
90deg,
#f0f0f0 25%,
#e0e0e0 50%,
#f0f0f0 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
示例3:通知消息入场/出场
css
/* 入场动画 */
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 出场动画 */
@keyframes slideOutRight {
from {
opacity: 1;
transform: translateX(0);
}
to {
opacity: 0;
transform: translateX(100%);
}
}
.notification-enter {
animation: slideInRight 0.3s ease forwards;
}
.notification-exit {
animation: slideOutRight 0.3s ease forwards;
}
六、面试高频问题
Q1:transition 和 animation 的区别?
答:
触发方式:transition 需要触发(hover/click/class变化),animation 可以自动执行
关键帧:transition 只有起点和终点,animation 可以定义多个关键帧
循环播放:transition 不支持循环,animation 支持 infinite 无限循环
控制能力:animation 可以控制播放方向、暂停、结束后状态等
简单来说:transition 适合简单的交互动画,animation 适合复杂的自动播放动画。
Q2:如何用 transition 实现循环动画?
答:
transition 本身不支持循环,可以通过 JS 添加/移除 class 来模拟循环。但更推荐用 animation。
Q3:animation 的 fill-mode 有什么作用?
答:
animation-fill-mode决定动画结束后元素的样式:
none(默认):回到动画前样式
forwards:保持动画最后一帧样式
backwards:保持动画第一帧样式
both:同时应用 forwards 和 backwards