C53. CSS 动画
3.1. ⭐ CSS 动画基础
动画是现代 UI 的重要特征,也是 CSS 突破“静态”的局限,开发动态的无限潜能的重要一步。
3.1.1 @keyframes定义动画序列
通过 @keyframes
规则定义动画的关键帧,控制元素在不同时间点的样式变化。
核心特点:
- 动画名称唯一(如
blink
) - 用
0%~100%
或from/to
定义动画过程 - 可添加中间状态(如
50%
)
css
/* 闪烁动画示例 */
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.blink-element {
animation: blink 1s infinite;
}
html
<div class="blink-element">闪烁文字</div>
3.1.2 动画属性
核心属性速查表:
属性名称 | 作用 | 快速记忆口诀 |
---|---|---|
animation-duration | 动画持续时间 | 时长(如2s ) |
animation-delay | 动画延迟启动时间 | 等等再开始(如0.5s ) |
animation-fill-mode | 结束后样式保留 | 记住最后的样子(forwards ) |
animation-iteration-count | 动画重复次数 | 无限循环(infinite ) |
以上内容全部可以“塞进”animation
属性中作为简写,顺序只需注意第一个时间值作为 <animation-duration>
,而第二个时间值(如果存在)作为 <animation-delay>
。
INFO
因篇幅有限,不引入过多的属性名称。可参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_animations/Using_CSS_animations。
3.1.3 常见问题
动画不执行?三步排查法:
- 是否写了
animation-duration
? @keyframes
名称和animation-name
是否一致?- 元素是否被其他样式覆盖?
3.2. 🌟 CSS 动画实现示例
CSS 动画实现有许多技巧、“定式”。先阅读这些基本的代码,然后从中学习 CSS 动画的基本用法,创造自己的动画。
3.2.1 旋转+缩放动画
css
@keyframes spinScale {
0% { transform: rotate(0deg) scale(1); }
50% { transform: rotate(180deg) scale(1.2); }
100% { transform: rotate(360deg) scale(1); }
}
.spinner {
width: 100px;
height: 100px;
margin: 100px;
background: #4CAF50;
animation: spinScale 2s infinite ease-in-out;
}
html
<div class="spinner"></div>
3.2.2 按钮悬停动画
css
.button {
padding: 12px 24px;
background: #2196F3;
transition: all 0.3s ease;
}
.button:hover {
animation: pulse 0.5s ease-in-out;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
html
<button class="button">点击我</button>
3.2.3 无限加载动画
css
.loader {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498DB;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
html
<div class="loader"></div>
3.3 (拓展)gasp.js 动画集成
CSS 动画毕竟具有局限性和较高的兼容性要求。真正的“动态语言”——JavaScript,提供了更丰富的动画功能。
GSAP 轮播图实战:
html
<div class="carousel">
<div class="slide" style="background: url(img1.jpg)">Slide 1</div>
<div class="slide" style="background: url(img2.jpg)">Slide 2</div>
<div class="slide" style="background: url(img3.jpg)">Slide 3</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.7/dist/gsap.min.js"></script>
<script>
const slides = document.querySelectorAll('.slide');
let currentIndex = 0;
function nextSlide() {
gsap.to(slides[currentIndex], { duration: 0.5, x: '-100%' });
currentIndex = (currentIndex + 1) % slides.length;
gsap.fromTo(slides[currentIndex], { x: '100%' }, { duration: 0.5, x: '0%' });
}
setInterval(nextSlide, 3000);
</script>
知识回顾
@keyframes 动画序列
- 通过
@keyframes
定义动画关键帧,控制样式在时间轴上的变化 - 关键帧名称需唯一,用
0%~100%
或from/to
定义动画过程 - 可添加中间状态(如
50%
)实现复杂动画效果
- 通过
核心动画属性
属性名称 作用 快速记忆 animation-duration
动画持续时间 必须设置,否则不执行 animation-delay
延迟启动时间 默认0 animation-fill-mode
结束后样式保留 forwards
保持最终状态animation-iteration-count
重复次数 infinite
无限循环动画执行三要素
css.element { animation: 名称 持续时间 速度曲线 延迟 次数 填充模式; }
- 简写时必须包含
animation-duration
,animation-delay
可选
- 简写时必须包含
性能优化技巧
- 优先使用
transform
和opacity
属性实现动画(GPU加速) - 避免在动画中触发重排的属性(如
width/height
) - 使用
will-change
提示浏览器提前优化
- 优先使用
常见问题排查
- 动画未执行?检查:
- 是否设置
animation-duration
@keyframes
名称与animation-name
是否一致- 是否被
display: none
等样式覆盖
- 是否设置
- 动画未执行?检查:
课后练习
补全
@keyframes
动画定义:css.slide-element { animation: slideIn 1s ease-out forwards; }
补全消失动画的
@keyframes
规则:css.fade { animation: fadeOut 1s forwards; }
设计一个「文字打字机」效果:
- 逐字显示文字
- 使用
@keyframes
- 添加打字机光标闪烁
参考答案
参考:
css@keyframes slideIn { 0% { transform: translateX(-100%); } 100% { transform: translateX(0); } }
参考:
css@keyframes fadeOut { 0% { opacity: 1; } 100% { opacity: 0; } }
文字打字机效果实现:
css/* 打字机效果核心样式 */ @keyframes typing { 0% { width: 0; } 100% { width: 100%; } } @keyframes blink { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } } .typewriter { white-space: nowrap; overflow: hidden; border-right: 2px solid #000; width: fit-content; animation: typing 2s steps(20, end), blink 0.5s infinite; } /* 光标闪烁优化 */ .typewriter::after { content: ''; animation: blink 0.7s infinite; }
html<div class="typewriter">Hello World!</div>