第9章: CSS动画与变换
🎯 本章重点
- CSS变换(Transforms)2D和3D
- CSS动画(Animations)关键帧和属性
- 性能优化和硬件加速
- 现代动画技术和最佳实践
📖 内容概述
9.1 CSS变换基础
9.1.1 2D变换
.transform-2d {
transform:
translate(50px, 100px) /* 移动 */
rotate(45deg) /* 旋转 */
scale(1.5) /* 缩放 */
skew(30deg, 20deg); /* 倾斜 */
}
/* 单独变换属性 */
.separate-transforms {
translate: 50px 100px;
rotate: 45deg;
scale: 1.5;
skew: 30deg 20deg;
}
9.1.2 变换原点
.transform-origin-example {
transform: rotate(45deg);
transform-origin: top left; /* 左上角 */
/* 其他值: center, bottom right, 50% 50%, 100px 200px */
}
9.2 3D变换
9.2.1 3D变换基础
.container-3d {
perspective: 1000px; /* 透视距离 */
transform-style: preserve-3d; /* 保持3D空间 */
}
.card-3d {
transform:
rotateX(45deg) /* X轴旋转 */
rotateY(30deg) /* Y轴旋转 */
rotateZ(15deg) /* Z轴旋转 */
translate3d(50px, 0, 100px); /* 3D移动 */
}
/* 背面可见性 */
.card-3d {
backface-visibility: hidden; /* 隐藏背面 */
}
9.2.2 3D变换函数
.advanced-3d {
transform:
matrix3d( /* 3D矩阵变换 */
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
50, 100, 0, 1
)
perspective(500px) /* 单独透视 */
rotate3d(1, 1, 1, 45deg); /* 自定义轴旋转 */
}
9.3 CSS过渡
9.3.1 过渡基础
.transition-basic {
transition: all 0.3s ease-in-out;
}
/* 详细配置 */
.transition-detailed {
transition-property: transform, opacity, background-color;
transition-duration: 0.3s, 0.5s, 0.2s;
transition-timing-function: ease-in, ease-out, linear;
transition-delay: 0s, 0.1s, 0.2s;
}
9.3.2 缓动函数
/* 内置缓动函数 */
.easing-examples {
transition-timing-function:
ease, /* 默认 */
ease-in, /* 加速 */
ease-out, /* 减速 */
ease-in-out, /* 加速然后减速 */
linear, /* 匀速 */
step-start, /* 步进开始 */
step-end, /* 步进结束 */
steps(4, jump-start); /* 4步进 */
}
/* 自定义三次贝塞尔 */
.custom-easing {
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
9.4 CSS动画
9.4.1 关键帧动画
@keyframes slide-in {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes bounce {
0%, 20%, 53%, 80%, 100% {
transform: translate3d(0, 0, 0);
}
40%, 43% {
transform: translate3d(0, -30px, 0);
}
70% {
transform: translate3d(0, -15px, 0);
}
90% {
transform: translate3d(0, -4px, 0);
}
}
.animated-element {
animation: slide-in 0.6s ease-out, bounce 1s ease-in-out 0.6s;
}
9.4.2 动画属性控制
.animation-controls {
animation-name: slide-in, fade-in;
animation-duration: 0.6s, 0.8s;
animation-timing-function: ease-out, ease-in;
animation-delay: 0s, 0.3s;
animation-iteration-count: 1, infinite;
animation-direction: normal, alternate;
animation-fill-mode: both, none;
animation-play-state: running, paused;
}
/* 简写形式 */
.animation-shorthand {
animation:
slide-in 0.6s ease-out,
fade-in 0.8s ease-in 0.3s infinite alternate;
}
9.5 性能优化
9.5.1 硬件加速
.performance-optimized {
/* 触发GPU加速的属性 */
transform: translateZ(0);
will-change: transform, opacity;
/* 避免重排的属性 */
opacity: 0.9;
filter: blur(5px);
}
/* 仅对需要动画的元素使用will-change */
.animating-element {
will-change: transform;
}
/* 动画结束后移除will-change */
.animating-element.animation-ended {
will-change: auto;
}
9.5.2 合成层优化
.composite-layer {
/* 创建独立的合成层 */
transform: translateZ(0);
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
}
/* 避免不必要的重绘 */
.no-repaint {
/* 使用transform代替top/left */
transform: translate(100px, 50px);
/* 使用opacity代替visibility */
opacity: 0;
}
9.6 现代动画技术
9.6.1 滚动触发动画
.scroll-animation {
animation: fade-in-up 1s ease-out;
animation-timeline: view();
animation-range: entry 0% cover 50%;
}
@keyframes fade-in-up {
from {
opacity: 0;
transform: translateY(100px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
9.6.2 视图时间线动画
.view-timeline-animation {
animation:
reveal linear,
fade-in linear;
animation-timeline:
view(block),
scroll(root block);
animation-range:
contain 0% contain 100%,
entry 0% cover 50%;
}
@keyframes reveal {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
9.7 交互式动画
9.7.1 鼠标悬停动画
.hover-card {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.hover-card:hover {
transform:
translateY(-8px)
scale(1.02);
box-shadow:
0 20px 25px -5px rgba(0, 0, 0, 0.1),
0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
/* 悬停子元素动画父元素 */
.parent:hover .child {
animation: bounce 0.5s ease-in-out;
}
9.7.2 焦点和活动状态
.input-animation {
transition: all 0.2s ease-out;
}
.input-animation:focus {
transform: scale(1.02);
box-shadow:
0 0 0 3px rgba(59, 130, 246, 0.1),
0 0 0 1px rgba(59, 130, 246, 0.5);
}
.button-press:active {
transform: scale(0.95);
transition: transform 0.1s ease-out;
}
9.8 高级动画模式
9.8.1 交错动画
.stagger-animation > * {
animation: fade-in-up 0.6s ease-out both;
}
.stagger-animation > *:nth-child(1) { animation-delay: 0.1s; }
.stagger-animation > *:nth-child(2) { animation-delay: 0.2s; }
.stagger-animation > *:nth-child(3) { animation-delay: 0.3s; }
.stagger-animation > *:nth-child(4) { animation-delay: 0.4s; }
/* 使用CSS变量 */
.stagger-vars > * {
--delay: calc(var(--index) * 0.1s);
animation-delay: var(--delay);
}
9.8.2 无限循环动画
.pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
9.9 动画性能监控
9.9.1 性能检测
// 检测动画性能
function measureAnimationPerformance() {
const element = document.querySelector('.animated-element');
const startTime = performance.now();
element.addEventListener('animationend', () => {
const duration = performance.now() - startTime;
console.log(`Animation took ${duration}ms`);
// 检查帧率
const frameRate = calculateFrameRate();
console.log(`Average frame rate: ${frameRate}fps`);
});
}
// 使用Performance API
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log('Animation frame time:', entry.duration);
});
});
observer.observe({ entryTypes: ['animation'] });
9.9.2 降级策略
/* 检测减少运动偏好 */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
.reduced-motion {
animation: none;
transition: none;
}
}
/* JavaScript检测 */
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.documentElement.classList.add('reduced-motion');
}
9.10 实用动画库模式
9.10.1 动画工具类
/* 淡入动画 */
.fade-in {
animation: fadeIn 0.6s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* 滑入动画 */
.slide-in-left {
animation: slideInLeft 0.6s ease-out;
}
@keyframes slideInLeft {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
/* 弹跳动画 */
.bounce-in {
animation: bounceIn 0.6s ease-out;
}
@keyframes bounceIn {
0% {
transform: scale(0.3);
opacity: 0;
}
50% {
transform: scale(1.05);
}
70% {
transform: scale(0.9);
}
100% {
transform: scale(1);
opacity: 1;
}
}
9.10.2 动画状态管理
.animation-states {
/* 初始状态 */
opacity: 0;
transform: translateY(50px);
}
.animation-states.animate-in {
animation: fadeInUp 0.6s ease-out forwards;
}
.animation-states.animate-out {
animation: fadeOutDown 0.6s ease-in forwards;
}
@keyframes fadeInUp {
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeOutDown {
to {
opacity: 0;
transform: translateY(50px);
}
}
💡 动画最佳实践总结
- 性能优先: 使用transform和opacity实现动画
- 硬件加速: 合理使用will-change和translateZ(0)
- 可访问性: 尊重减少运动偏好
- 渐进增强: 提供适当的降级方案
- 状态管理: 使用CSS类控制动画状态
🎯 下一章预览
下一章将探讨现代CSS布局技术,包括容器查询、层叠上下文和CSS嵌套等高级特性。
最后更新: 2024年12月