20、css3动画有哪些?
目录
🎯 核心概念速览
CSS3 动画主要分为三大体系:
CSS3 动画体系
├── Transition(过渡) → 状态A到 状态B 的平滑变化
├── Animation(关键帧动画)→ 多阶段、可循环、更复杂的动画
└── Transform(变换) → 位移/旋转/缩放/倾斜(动画的基础)
+ 附加能力├── 3D Transform→ 三维空间变换
└── will-change → 性能优化提示
⭐ 高分回答模板
面试官问:CSS3 动画有哪些?请详细说说。
"CSS3 动画我会从三大核心机制讲起,再延伸到性能优化和实战应用。"
第一部分:Transition 过渡动画
transition是最简单的动画形式,
本质是:当属性值发生变化时,以动画的形式平滑过渡。
适合做简单的交互反馈。
基础语法
/* 完整语法 */
transition: property duration timing-function delay;
/*属性名 持续时间缓动函数 延迟时间 */
/* 示例 */
.button {
background: #3498db;
transform: scale(1);
/* 单个属性 */
transition: background 0.3s ease;
/* 多个属性 */
transition:
background 0.3s ease,
transform 0.2s ease-out;
/* 全部属性(不推荐,性能差)*/
transition: all 0.3s ease;
}
.button:hover {
background: #2980b9;
transform: scale(1.05);
}
timing-function 缓动函数详解
.box {
/* 内置关键字 */
transition-timing-function: linear; /* 匀速 ━━━━━━━━━━ */
transition-timing-function: ease; /* 默认:慢-快-慢 */
transition-timing-function: ease-in; /* 由慢到快(加速)*/
transition-timing-function: ease-out; /* 由快到慢(减速)*/
transition-timing-function: ease-in-out; /* 慢-快-慢(对称)*/
/* 自定义贝塞尔曲线(最灵活)*/
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);/*弹性效果!超出再回弹 */
/* 阶梯函数(逐帧效果)*/
transition-timing-function: steps(5, start); /* 分5步跳跃 */
transition-timing-function: steps(1, end);
}
实战示例:卡片悬浮效果
.card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transform: translateY(0);
transition:
transform 0.3s ease-out,
box-shadow 0.3s ease-out;
}
.card:hover {
transform: translateY(-8px); /* 上浮 */
box-shadow: 0 16px 32px rgba(0,0,0,0.15); /* 阴影加深 */
}
Transition 的局限性
❌ 无法自动触发(必须有状态变化,如 :hover)
❌ 只能定义起点和终点,不能设置中间状态
❌ 无法循环播放
❌ 无法设置播放次数
→ 这些问题由 Animation 解决!
第二部分:Animation 关键帧动画
animation是 CSS3 最强大的动画机制,
通过@keyframes定义多个关键帧,
支持循环、暂停、方向控制等高级特性。
基础语法
/* 第一步:定义关键帧 */
@keyframes slideIn {
/* 方式一:from/to(只有起止点)*/
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes bounce {
/* 方式二:百分比(多个关键帧)*/
0%{ transform: translateY(0);}
30% { transform: translateY(-30px);}
50% { transform: translateY(-20px);}
70% { transform: translateY(-30px);}
100% { transform: translateY(0); }
}
/* 第二步:应用动画 */
.element {
animation: slideIn 0.5s ease-out forwards;
/*名称 时长缓动 结束状态保持 */
}
八大属性详解
.animated-box {
animation-name:bounce; /* 关键帧名称 */
animation-duration: 1s; /* 持续时间 */
animation-timing-function: ease-in-out; /* 缓动函数 */
animation-delay: 0.5s; /* 延迟开始 */
animation-iteration-count: infinite; /* 播放次数:infinite=无限 */
animation-direction: alternate; /* 方向:alternate=正反交替 */
animation-fill-mode: forwards;/* 结束状态:forwards=保持结束帧 */
animation-play-state: running; /* 播放状态:paused=暂停 */
/* 简写(顺序重要!duration在delay 前面)*/
animation: bounce 1s ease-in-out 0.5s infinite alternate forwards;
}
animation-direction 详解
.box {
/* normal(默认): 0% → 100%,循环重置 */
animation-direction: normal;
/* reverse: 100% → 0%,反向播放 */
animation-direction: reverse;
/* alternate: 0%→100%→0%→100%正反交替 ✅常用 */
animation-direction: alternate;
/* alternate-reverse: 100%→0%→100%→0% */
animation-direction: alternate-reverse;
}
animation-fill-mode 详解
.box {
/* none(默认): 动画前后都回到初始状态 */
animation-fill-mode: none;
/* forwards: 动画结束后保持最后一帧 ✅ 常用 */
animation-fill-mode: forwards;
/* backwards: 动画开始前就应用第一帧(配合delay使用)*/
animation-fill-mode: backwards;
/* both: forwards + backwards 都应用 */
animation-fill-mode: both;
}
JS 控制动画
const el = document.querySelector('.box');
// 暂停动画
el.style.animationPlayState = 'paused';
// 继续动画
el.style.animationPlayState = 'running';
// 重新播放(先移除再添加 class)
el.classList.remove('animate');
void el.offsetWidth; // 强制回流,触发重绘
el.classList.add('animate');
// 监听动画事件
el.addEventListener('animationstart',() => console.log('动画开始'));
el.addEventListener('animationend', () => console.log('动画结束'));
el.addEventListener('animationiteration',() => console.log('每次循环'));
实战示例:加载动画
/*旋转加载圈 */
@keyframes spin {
to { transform: rotate(360deg); }
}
.loader {
width: 40px;
height: 40px;
border: 4px solid #f0f0f0;
border-top-color: #3498db;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
/*骨架屏闪光效果 */
@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;
}
/* 心跳效果 */
@keyframes heartbeat {
0%, 100% { transform: scale(1); }
15%{ transform: scale(1.3); }
30% { transform: scale(1);}
45% { transform: scale(1.2); }
}
.heart {
animation: heartbeat 1.5s ease-in-out infinite;
}
第三部分:Transform 变换
transform本身不是动画,
但它是 CSS 动画最重要的执行载体,
因为transform 的变化不触发重排,性能极佳!
2D Transform
.box {
/*① 位移:不影响其他元素布局(不同于margin!)*/
transform: translateX(100px);
transform: translateY(-50px);
transform: translate(100px, -50px); /* X轴,Y轴 */
transform: translateX(50%); /* 相对自身宽度 */
/* ② 旋转:单位deg(度)*/
transform: rotate(45deg); /* 顺时针45度 */
transform: rotate(-90deg); /* 逆时针90度 */
/* ③ 缩放:1=原始,<1缩小,>1放大 */
transform: scale(1.5); /* 等比放大1.5倍 */
transform: scale(1.2, 0.8); /* X放大,Y缩小 */
transform: scaleX(0);/* 水平方向收缩为0 */
/* ④ 倾斜 */
transform: skewX(30deg);
transform: skewY(15deg);
transform: skew(30deg, 15deg);
/* ⑤ 组合变换(顺序影响结果!)*/
transform: translateX(100px) rotate(45deg) scale(1.2);
}
/* transform-origin:变换原点 */
.box {
transform-origin: center center; /* 默认:中心点 */
transform-origin: top left; /* 左上角 */
transform-origin: 0 0; /* 同上 */
transform-origin: 50% 100%; /* 底部中心 */
}
3D Transform
/*开启3D空间(必须设置在父元素上)*/
.container {
perspective: 800px; /* 透视距离,越小透视效果越强 */
perspective-origin: center; /* 透视点位置 */
transform-style: preserve-3d;/* 子元素保持3D空间 */
}
.box {
/*3D位移 */
transform: translateZ(100px); /* 向屏幕外移动 */
transform: translate3d(50px, 50px, 100px); /* X,Y,Z轴 */
/* 3D旋转 */
transform: rotateX(45deg); /* 绕X轴旋转(上下翻转)*/
transform: rotateY(45deg); /* 绕Y轴旋转(左右翻转)*/
transform: rotateZ(45deg); /* 绕Z轴旋转(平面旋转)*/
transform: rotate3d(1, 1, 0, 45deg); /* 自定义轴旋转 */
/* 3D缩放 */
transform: scaleZ(2);
transform: scale3d(1.2, 1.2, 1);
}
实战示例:3D翻转卡片
<div class="card-container">
<div class="card">
<div class="card-front">正面</div>
<div class="card-back">背面</div>
</div>
</div>
.card-container {
perspective: 1000px; /* 透视距离 */
width: 200px;
height: 200px;
}
.card {
width: 100%;
height: 100%;
transform-style: preserve-3d; /* 保持3D */
transition: transform 0.6s ease;
position: relative;
}
.card:hover {
transform: rotateY(180deg); /* 悬停翻转 */
}
.card-front,
.card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;/* 背面不可见 */border-radius: 8px;
}
.card-front {
background: #3498db;
color: white;
}
.card-back {
background: #e74c3c;
color: white;
transform: rotateY(180deg); /* 初始旋转180度 */
}
第四部分:性能优化(加分项!)
"说到CSS 动画,不得不提性能优化,
这是区分初级和高级开发者的关键。"
触发层级对比
浏览器渲染管线:
JavaScript → Style → Layout → Paint → Composite
不同属性影响的阶段:
├── width/height/margin →触发 Layout(重排)→性能最差 ❌
├── color/background → 触发 Paint(重绘)→ 性能一般 ⚠️
└── transform/opacity → 只触发 Composite → 性能最好 ✅
/* ❌ 性能差的动画(触发重排)*/
@keyframes bad-animation {
from { width: 100px; margin-left: 0;}
to { width: 200px; margin-left: 50px;}
}
/* ✅ 性能好的动画(只触发合成层)*/
@keyframes good-animation {
from { transform: translateX(0) scaleX(1); }
to { transform: translateX(50px) scaleX(2); }
}
will-change:提前告知浏览器
/*提前告知浏览器,让它预先创建合成层 */
.animated-element {
will-change: transform, opacity;
/*浏览器会提前为该元素创建独立的合成层 */
}
/* ⚠️ 注意:不要滥用 will-change!*/
/*❌ 错误用法:给所有元素都加*/
* { will-change: transform; } /* 会消耗大量内存!*/
/* ✅ 正确用法:只在需要时,用 JS 动态添加/移除 */
el.addEventListener('mouseenter', () => {
el.style.willChange = 'transform';
});
el.addEventListener('animationend', () => {
el.style.willChange = 'auto'; /* 用完记得移除!*/
});
GPU 加速技巧
/* 强制开启 GPU 加速的方法 */
.gpu-accelerated {
/* 方式1:transform: translateZ(0) */
transform: translateZ(0);
/* 方式2:will-change */
will-change: transform;
/* 方式3:opacity< 1 */
opacity: 0.99; /* 不推荐,有副作用 */
}
/* ✅ 推荐:动画属性只用 transform 和 opacity */
@keyframes fade-slide {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
第五部分:现代 CSS 动画新特性(终极加分)
/* ① scroll-driven animations:滚动驱动动画(2023新特性)*/
@keyframes reveal {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0);}
}
.reveal-on-scroll {
animation: reveal linear both;
animation-timeline: view(); /* 以元素进入视口为时间轴 */
animation-range: entry 0% entry 50%;/* 进入视口0%-50%时播放 */
}
/* ② @starting-style:元素出现时的初始动画 */
.dialog {
transition: opacity 0.3s, transform 0.3s;opacity: 1;
transform: scale(1);
@starting-style {
opacity: 0; /* 元素首次出现时从这里开始过渡 */
transform: scale(0.9);
}
}
/* ③ prefers-reduced-motion:无障碍适配 */
@media (prefers-reduced-motion: reduce) {
/* 用户系统开启了"减少动画"选项 */
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;}
}
总结对比表
| 对比维度 | Transition | Animation | Transform |
|---|---|---|---|
| 触发方式 | 状态变化触发 | 自动/JS触发 | 配合前两者 |
| 关键帧 | 只有起止点 | 支持多关键帧 | — |
| 循环 | ❌ 不支持 | ✅ 支持 | — |
| 暂停控制 | ❌ | ✅ | — |
| 复杂程度 | 简单 | 复杂 | 中等 |
| 适用场景 | 交互反馈 | 复杂动画 | 变形效果 |
| 性能 | ✅ 好 | ✅ 好 | ✅ 最好 |
📝 简答模板
适合时间紧张时使用
"CSS3 动画主要有三大类:Transition、Animation 和 Transform。"
① Transition(过渡) :
状态改变时的平滑过渡,比如 hover时颜色渐变、大小变化,
只能定义起止两个状态,需要事件触发。
.btn {
background: blue;
transition: background 0.3s ease, transform 0.2s;
}
.btn:hover {
background: red;
transform: scale(1.05);
}
② Animation(关键帧动画) :
用@keyframes定义多个中间状态,
支持循环、暂停、方向控制,适合复杂动画。
@keyframes spin {
to { transform: rotate(360deg); }
}
.loader {
animation: spin 1s linear infinite;
}
③ Transform(变换) :
提供位移translate、旋转rotate、缩放scale、倾斜skew,
支持 2D 和 3D,性能最好(不触发重排重绘)。
.card:hover {
transform: translateY(-8px) scale(1.02) rotate(2deg);
}
性能原则:
动画优先用transform和opacity,
因为它们只触发 Composite(合成),不触发 Layout 重排,
性能比修改width、margin好很多。
##💡 一句话记忆法
- Transition = "我变化时,帮我变得优雅一点"🦋
- Animation = "我要自己跳舞,给我剧本(keyframes)" 💃
- Transform = "改变我的形态,但别打扰页面布局" 🎭
- 性能口诀 = "动画首选 transform + opacity,GPU扛着不重排!" 🚀
更多推荐
所有评论(0)