📖 核心概念
- CSS Transitions:状态过渡
- CSS Animations:关键帧动画
- Transform:2D/3D变换
- 性能优化:will-change与GPU加速
- 动画时序函数深入
- 交互反馈动画设计
💻 代码实现
过渡与变换
✅ css
/* 按钮悬停效果 */
.btn-fancy {
padding: 0.75rem 2rem;
background: #06b6d4;
color: #0f172a;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
transform: translateZ(0); /* GPU加速 */
}
.btn-fancy:hover {
transform: translateY(-2px) scale(1.02);
box-shadow: 0 8px 25px rgba(6, 182, 212, 0.4);
}
.btn-fancy:active {
transform: translateY(0) scale(0.98);
}
/* 卡片翻转效果 */
.card-flip {
perspective: 1000px;
width: 300px;
height: 400px;
}
.card-flip-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
.card-flip:hover .card-flip-inner {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 12px;
}
.card-back {
transform: rotateY(180deg);
background: #06b6d4;
}
关键帧动画
✅ css
/* 脉冲动画 */
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.05); opacity: 0.8; }
}
.pulse { animation: pulse 2s ease-in-out infinite; }
/* 加载动画 */
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 40px; height: 40px;
border: 3px solid #1e293b;
border-top-color: #06b6d4;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
/* 打字机效果 */
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink {
50% { border-color: transparent; }
}
.typewriter {
overflow: hidden;
white-space: nowrap;
border-right: 2px solid #06b6d4;
width: 0;
animation:
typing 3s steps(30) forwards,
blink 0.7s step-end infinite;
}
/* 骨架屏 */
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.skeleton {
background: linear-gradient(90deg, #1e293b 25%, #2d3a4f 50%, #1e293b 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: 8px;
}
/* 淡入上滑 */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in-up {
opacity: 0;
animation: fadeInUp 0.6s ease-out forwards;
}
.fade-in-up:nth-child(2) { animation-delay: 0.1s; }
.fade-in-up:nth-child(3) { animation-delay: 0.2s; }
🔍 动画性能与设计原则
60fps动画的性能准则
流畅的动画需要保持60fps,即每帧必须在16.67ms内完成。以下是确保性能的关键原则:
- 只动画合成属性 — transform 和 opacity 由GPU合成层处理,不触发布局重计算
- 避免布局抖动 — 读取offsetWidth后立即修改width会导致强制同步布局
- 使用will-change — 提前告知浏览器哪些属性将变化,但不要滥用
- 减少绘制区域 — 避免大面积重绘,使用contain属性限制影响范围
动画设计原则
好的动画不仅是技术实现,更是设计决策:
- 有目的性 — 每个动画都应该传达信息(状态变化、空间关系、引导注意力)
- 快速响应 — 交互反馈应在100ms内开始,让用户感到即时
- 自然流畅 — 使用ease-out让进入动画感觉自然,ease-in让退出动画感觉果断
- 克制使用 — 过多动画会分散注意力,影响专业感
prefers-reduced-motion
尊重用户的运动偏好设置是基本的无障碍要求:
减少动画适配
✅ css
/* 默认有动画 */
.animated-element {
transition: transform 0.3s ease;
}
/* 用户偏好减少动画 */
@media (prefers-reduced-motion: reduce) {
.animated-element {
transition: none;
animation: none;
}
}
/* JavaScript检测 */
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
🎯 练习任务
- 1 实现一个汉堡菜单的CSS动画(三条线变X)
- 2 创建一个纯CSS的加载动画集(3种以上)
- 3 实现scroll-triggered动画(用IntersectionObserver)
- 4 优化一个动画的性能,确保60fps流畅运行
🏆 成就解锁
动画魔法师 — 用CSS动画让页面活起来,创造流畅自然的交互体验