什么是CSS动画?
CSS动画允许您创建复杂的动画效果,而无需使用JavaScript。通过@keyframes规则,您可以定义动画序列中的各个阶段。CSS动画比过渡更强大,可以创建多阶段、循环和复杂的动画序列。
动画 vs 过渡:
- 过渡:需要触发条件,简单属性变化
- 动画:自动播放或通过类触发,复杂关键帧序列
- 动画支持循环、反向、暂停等高级功能
- 动画更适合创建复杂的连续效果
CSS动画示例 - 脉冲效果
@keyframes规则
@keyframes规则用于定义动画序列,可以指定动画在不同时间点的样式:
CSS
@keyframes animationName {
0% {
/* 起始状态 */
opacity: 0;
transform: translateX(-100px);
}
50% {
/* 中间状态 */
opacity: 1;
transform: translateX(0);
}
100% {
/* 结束状态 */
opacity: 0;
transform: translateX(100px);
}
}
使用from和to
对于简单的两阶段动画,可以使用from和to关键字:
CSS
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
多阶段动画
可以定义任意数量的关键帧:
CSS
@keyframes complexAnimation {
0% { transform: translateY(0) rotate(0deg); }
25% { transform: translateY(-50px) rotate(90deg); }
50% { transform: translateY(0) rotate(180deg); }
75% { transform: translateY(50px) rotate(270deg); }
100% { transform: translateY(0) rotate(360deg); }
}
动画属性
CSS动画涉及多个属性来控制动画的行为:
| 属性 | 描述 | 示例 | 默认值 |
|---|---|---|---|
| animation-name | 指定@keyframes动画的名称 | fadeIn, slideIn | none |
| animation-duration | 指定动画完成一个周期所需时间 | 1s, 500ms | 0s |
| animation-timing-function | 指定动画的速度曲线 | ease, linear, ease-in-out | ease |
| animation-delay | 指定动画开始前的延迟时间 | 0s, 1s | 0s |
| animation-iteration-count | 指定动画播放次数 | 1, 3, infinite | 1 |
| animation-direction | 指定动画播放方向 | normal, reverse, alternate | normal |
| animation-fill-mode | 指定动画执行前后如何应用样式 | none, forwards, backwards | none |
| animation-play-state | 指定动画播放状态 | running, paused | running |
animation-fill-mode详解
控制动画执行前后元素的样式:
CSS
/* 默认值,动画前后不应用任何样式 */
.element {
animation-fill-mode: none;
}
/* 动画完成后保持最后一帧的样式 */
.element {
animation-fill-mode: forwards;
}
/* 动画开始前应用第一帧的样式 */
.element {
animation-fill-mode: backwards;
}
/* 同时应用forwards和backwards */
.element {
animation-fill-mode: both;
}
animation-direction详解
控制动画播放方向:
CSS
/* 正常播放 */
.element {
animation-direction: normal;
}
/* 反向播放 */
.element {
animation-direction: reverse;
}
/* 先正常再反向,交替播放 */
.element {
animation-direction: alternate;
}
/* 先反向再正常,交替播放 */
.element {
animation-direction: alternate-reverse;
}
动画简写属性
可以使用animation简写属性同时设置所有动画属性:
CSS
.element {
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
}
示例
CSS
.box {
animation: slideIn 1s ease 0.5s 3 alternate;
}
/* 等同于: */
.box {
animation-name: slideIn;
animation-duration: 1s;
animation-timing-function: ease;
animation-delay: 0.5s;
animation-iteration-count: 3;
animation-direction: alternate;
}
多个动画
可以为元素应用多个动画:
CSS
.element {
animation:
fadeIn 1s ease,
slideIn 0.5s ease 0.5s;
}
常见动画示例
淡入效果
CSS
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fade-in {
animation: fadeIn 1s ease;
}
弹跳效果
CSS
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-30px);
}
60% {
transform: translateY(-15px);
}
}
.bounce {
animation: bounce 2s infinite;
}
旋转加载动画
CSS
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.spinner {
animation: spin 1s linear infinite;
}
脉冲效果
CSS
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: 0.7;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.pulse {
animation: pulse 2s infinite;
}
打字机效果
CSS
@keyframes typing {
from {
width: 0;
}
to {
width: 100%;
}
}
@keyframes blink {
0%, 100% {
border-color: transparent;
}
50% {
border-color: black;
}
}
.typewriter {
overflow: hidden;
border-right: 2px solid;
white-space: nowrap;
animation: typing 3s steps(40, end), blink 1s infinite;
}
动画事件
JavaScript可以监听动画的开始、结束、迭代和取消事件:
JavaScript
const element = document.querySelector('.animated-element');
// 动画开始
element.addEventListener('animationstart', function(event) {
console.log('动画开始:', event.animationName);
});
// 动画结束
element.addEventListener('animationend', function(event) {
console.log('动画结束:', event.animationName);
});
// 动画迭代
element.addEventListener('animationiteration', function(event) {
console.log('动画迭代:', event.animationName);
});
// 动画取消
element.addEventListener('animationcancel', function(event) {
console.log('动画取消:', event.animationName);
});
动画效果演示
Demo
当前动画: 无
状态: 未开始
迭代次数: 0
动画事件将显示在这里...
当前动画CSS代码:
CSS
/* 选择动画类型查看代码 */
动画性能优化
使用transform和opacity: 这些属性可以由GPU加速,性能更好。
避免布局抖动: 避免在动画中修改会影响布局的属性,如width、height、margin等。
使用will-change: 提前告知浏览器元素将要发生的变化,以便优化。
减少复合操作: 避免同时动画多个复杂属性。
CSS
/* 性能优化示例 */
.optimized-element {
will-change: transform, opacity;
animation: slideIn 1s ease;
}
/* 避免这样做 */
.unoptimized-element {
animation: complexAnimation 1s ease; /* 可能包含布局属性 */
}
性能优化属性列表
| 性能优秀 | 性能一般 | 性能较差 |
|---|---|---|
| transform | color | width |
| opacity | background-color | height |
| filter | border-color | margin |
| backdrop-filter | font-size | padding |
动画与可访问性
减少动画偏好: 尊重用户的系统偏好设置,为偏好减少动画的用户提供替代方案。
CSS
/* 基础动画效果 */
.animated-element {
animation: bounce 2s infinite;
}
/* 为偏好减少动画的用户移除动画 */
@media (prefers-reduced-motion: reduce) {
.animated-element {
animation: none;
}
}
渐进增强动画
CSS
/* 基础样式 */
.element {
opacity: 0;
}
/* 支持动画的设备应用动画 */
@media (prefers-reduced-motion: no-preference) {
.element {
animation: fadeIn 1s ease forwards;
}
}
/* 不支持动画的设备直接显示 */
@media (prefers-reduced-motion: reduce) {
.element {
opacity: 1;
}
}
现代动画技术
1. 自定义属性与动画
使用CSS自定义属性创建动态动画:
CSS
:root {
--animation-duration: 1s;
--animation-delay: 0s;
}
.element {
animation: slideIn var(--animation-duration) ease var(--animation-delay);
}
2. 滚动驱动动画
CSS Scroll-Driven Animations(实验性功能):
CSS
@keyframes reveal {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.scroll-animation {
animation: reveal linear;
animation-timeline: view();
}
3. 视图过渡API
View Transitions API(实验性功能):
JavaScript
// 启用视图过渡
if (document.startViewTransition) {
document.startViewTransition(() => {
// 更新DOM
updateTheDOMSomehow();
});
}