CSS3 动画有哪些?
CSS3 动画让网页从静态变为动态,是提升用户体验的重要手段。面试考察这个问题,是想要了解候选人对 CSS 动画技术的全面掌握,包括过渡、变换和关键帧动画的使用和区别。
约 4 分钟
CSS3 动画有哪些?
问题解析
CSS3 动画让网页从静态变为动态,是提升用户体验的重要手段。面试考察这个问题,是想要了解候选人对 CSS 动画技术的全面掌握,包括过渡、变换和关键帧动画的使用和区别。
CSS 实现动画的三种方式
| 方式 | 特点 | 适用场景 |
|---|---|---|
| Transition | 简单过渡,需触发条件 | 状态变化(hover、focus 等) |
| Transform | 视觉变换,性能好 | 位移、旋转、缩放等 |
| Animation | 复杂关键帧动画 | 循环、复杂路径动画 |
1. Transition 过渡动画
基本用法
.button {
background: blue;
transition: background 0.3s ease;
}
.button:hover {
background: red;
}
完整属性
.element {
/* 简写 */
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
/* 详细 */
transition-property: width, height, background-color;
transition-duration: 0.3s;
transition-timing-function: ease-in-out;
transition-delay: 0.1s;
}
时间函数
/* 预设值 */
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: step(4); /* 分步动画 */
/* 自定义贝塞尔曲线 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); /* 弹性效果 */
触发条件
Transition 需要状态变化才能触发:
/* 伪类触发 */
.element:hover { transform: scale(1.1); }
.element:focus { border-color: blue; }
/* 类切换 */
.element.active { opacity: 1; }
/* 属性变化(通过 JS) */
.element.style.width = '200px';
2. Transform 变换
Transform 常与 Transition/Animation 配合使用。
2D 变换
.element {
/* 位移 */
transform: translate(50px, 100px); /* x, y */
transform: translateX(50px);
transform: translateY(100px);
/* 缩放 */
transform: scale(1.5); /* 等比缩放 */
transform: scale(1.2, 0.8); /* x, y 不等比 */
transform: scaleX(-1); /* 水平翻转 */
/* 旋转 */
transform: rotate(45deg);
transform: rotate(0.5turn); /* 半圈 */
/* 倾斜 */
transform: skew(30deg, 10deg);
/* 组合(从右向左执行) */
transform: translateX(100px) rotate(45deg) scale(1.5);
}
3D 变换
.container {
perspective: 1000px; /* 透视距离 */
perspective-origin: center center; /* 透视原点 */
}
.element {
transform-style: preserve-3d; /* 保持 3D */
/* 3D 变换 */
transform: translate3d(50px, 100px, 200px);
transform: rotate3d(1, 1, 0, 45deg); /* x, y, z轴 + 角度 */
transform: rotateX(45deg);
transform: rotateY(45deg);
transform: scaleZ(2);
/* 背面可见性 */
backface-visibility: hidden;
}
变换原点
.element {
transform-origin: center center; /* 默认值 */
transform-origin: top left;
transform-origin: 100% 100%;
transform-origin: 50px 50px;
}
3. Animation 关键帧动画
基本用法
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.element {
animation: slideIn 0.5s ease-out forwards;
}
多关键帧动画
@keyframes bounce {
0%, 100% {
transform: translateY(0);
animation-timing-function: ease-out;
}
50% {
transform: translateY(-20px);
animation-timing-function: ease-in;
}
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.element {
animation: bounce 1s infinite;
}
完整属性
.element {
/* 简写 */
animation: slideIn 0.5s ease 0.1s 3 alternate forwards running;
/* 详细 */
animation-name: slideIn; /* 动画名称 */
animation-duration: 0.5s; /* 持续时间 */
animation-timing-function: ease; /* 时间函数 */
animation-delay: 0.1s; /* 延迟 */
animation-iteration-count: 3; /* 播放次数(infinite 无限) */
animation-direction: normal; /* 播放方向 */
animation-fill-mode: forwards; /* 填充模式 */
animation-play-state: running; /* 播放状态 */
}
Animation 属性详解
| 属性 | 值 | 说明 |
|---|---|---|
| direction | normal/reverse/alternate/alternate-reverse | 播放方向 |
| fill-mode | none/forwards/backwards/both | 动画前后的样式 |
| play-state | running/paused | 播放/暂停 |
/* 填充模式示例 */
.fade-in {
opacity: 0;
animation: fadeIn 1s forwards; /* 保持结束状态 */
}
/* 播放状态控制 */
.paused:hover {
animation-play-state: paused;
}
深入理解
性能优化
/* 触发 GPU 加速的属性 */
.optimized {
will-change: transform, opacity; /* 提示浏览器优化 */
transform: translateZ(0); /* 强制 GPU 加速 */
}
/* 避免触发重排的属性 */
/* 好的属性:transform, opacity */
/* 避免:width, height, top, left, margin, padding */
requestAnimationFrame vs CSS 动画
| CSS 动画 | JS 动画 |
|---|---|
| 性能好(浏览器优化) | 控制更灵活 |
| 简单场景首选 | 复杂交互首选 |
| 脱离主线程 | 可以暂停/恢复 |
动画库选择
| 库 | 特点 | 适用场景 |
|---|---|---|
| CSS 原生 | 性能好,无依赖 | 简单动画 |
| Animate.css | 预设动画丰富 | 快速实现 |
| GSAP | 功能强大,专业级 | 复杂时间线动画 |
| Lottie | 支持 AE 导出 | 复杂矢量动画 |
| Framer Motion | React 生态 | React 项目 |
无障碍访问
/* 尊重用户的减少动画偏好 */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
实用动画效果
常用工具类
/* 淡入淡出 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
/* 缩放弹出 */
@keyframes popIn {
0% { transform: scale(0); opacity: 0; }
80% { transform: scale(1.1); }
100% { transform: scale(1); opacity: 1; }
}
/* 摇晃 */
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
/* 旋转加载 */
@keyframes spin {
to { transform: rotate(360deg); }
}
/* 脉冲 */
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
/* 滑动 */
@keyframes slideUp {
from { transform: translateY(100%); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
使用示例
/* 加载动画 */
.loading {
width: 40px;
height: 40px;
border: 3px solid #f3f3f3;
border-top-color: #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* 提示动画 */
.toast {
animation: slideUp 0.3s ease-out, fadeOut 0.3s ease-in 2.7s forwards;
}
/* 错误提示 */
.error-input {
animation: shake 0.5s ease-in-out;
}
面试要点
- 能够区分 transition 和 animation 的适用场景(深入阅读:CSS 实现动画的三种方式)
- 理解 transform 的性能优势和 GPU 加速原理(深入阅读:性能优化)
- 能够写出常用的关键帧动画(深入阅读:3. Animation 关键帧动画)
- 了解 will-change 和 transform: translateZ(0) 的作用(深入阅读:性能优化)
- 知道 prefers-reduced-motion 媒体查询的重要性(深入阅读:无障碍访问)
- 理解哪些属性会触发重排(reflow),哪些只会触发重绘(repaint)(深入阅读:性能优化)