CSS 动画:Transitions、Animations 与 Transform
CoreCSS VisualCSS 动画为网页带来 生命力——从简单的悬停效果到复杂的关键帧动画,让界面更具交互感和专业感。
一、🎭 三大动画工具概览
| 工具 | 用途 | 触发方式 | 复杂度 |
|---|---|---|---|
| Transition | 属性从 A 到 B 的 平滑过渡 | 需要触发(:hover 等) | ⭐ |
| Animation | 使用 关键帧 定义完整动画序列 | 自动运行 / 触发 | ⭐⭐⭐ |
| Transform | 元素的 几何变换(旋转/缩放/位移) | 常与 Transition/Animation 配合 | ⭐⭐ |
二、🔄 Transition(过渡)
2.1 基本语法
css
.button {
background-color: blue;
color: white;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: darkblue;
}当鼠标悬停时,背景色会在 0.3 秒内 平滑过渡 到深蓝色。
2.2 四个子属性
| 属性 | 说明 | 默认值 | 示例 |
|---|---|---|---|
transition-property | 要过渡的 CSS 属性 | all | background-color |
transition-duration | 过渡持续时间 | 0s | 0.3s、300ms |
transition-timing-function | 速度曲线 | ease | linear、ease-in-out |
transition-delay | 延迟开始时间 | 0s | 0.1s |
2.3 简写语法
css
/* transition: property duration timing-function delay */
.card {
transition: all 0.3s ease-in-out 0s;
}
/* 多个属性分别设置 */
.card {
transition:
background-color 0.3s ease,
transform 0.5s ease-in-out,
box-shadow 0.3s ease;
}2.4 速度曲线(Timing Functions)
| 值 | 说明 | 效果 |
|---|---|---|
linear | 匀速 | 始终相同速度 |
ease | 先快后慢(默认) | 自然感 |
ease-in | 先慢后快 | 加速进入 |
ease-out | 先快后慢 | 减速结束 |
ease-in-out | 慢-快-慢 | 最自然的动效 |
cubic-bezier(n,n,n,n) | 自定义曲线 | 完全可控 |
cubic-bezier 调试
Chrome DevTools 中点击 timing function 值旁的小方块,可以 可视化编辑 cubic-bezier 曲线。
2.5 可过渡的属性
不是所有 CSS 属性都能过渡。可过渡 的属性通常有 数值中间态:
| ✅ 可过渡 | ❌ 不可过渡 |
|---|---|
opacity | display |
color / background-color | font-family |
width / height | position |
margin / padding | float |
transform | content |
border-radius | visibility(可用但只能跳跃) |
box-shadow | grid-template-columns |
三、🎨 Transform(变换)
3.1 2D 变换
平移(Translate)
css
.box { transform: translate(50px, 20px); } /* 向右50px、向下20px */
.box { transform: translateX(50px); } /* 仅水平移动 */
.box { transform: translateY(-20px); } /* 向上移动20px */旋转(Rotate)
css
.box { transform: rotate(45deg); } /* 顺时针旋转45度 */
.box { transform: rotate(-90deg); } /* 逆时针旋转90度 */缩放(Scale)
css
.box { transform: scale(1.5); } /* 放大1.5倍 */
.box { transform: scale(0.5); } /* 缩小为一半 */
.box { transform: scaleX(2); } /* 仅水平拉伸2倍 */倾斜(Skew)
css
.box { transform: skew(10deg, 5deg); } /* X轴倾斜10度,Y轴5度 */
.box { transform: skewX(20deg); } /* 仅X轴倾斜 */3.2 组合变换
css
.box {
transform: translate(50px, 0) rotate(45deg) scale(1.2);
/* 先平移 → 再旋转 → 再缩放 */
}顺序很重要
多个变换函数的执行顺序是 从右到左(数学上是矩阵乘法)。不同顺序可能产生不同结果。
3.3 变换原点(Transform Origin)
css
.box {
transform-origin: top left; /* 以左上角为旋转/缩放中心 */
transform: rotate(45deg);
}默认值是 center center(元素中心点)。
3.4 3D 变换
css
/* 透视视距(设在父元素上) */
.container { perspective: 1000px; }
/* 3D 旋转 */
.card { transform: rotateY(180deg); } /* 沿Y轴翻转 */
.card { transform: rotateX(45deg); } /* 沿X轴倾斜 */
.card { transform: rotate3d(1, 1, 0, 45deg); } /* 自定义轴旋转 */
/* 3D 平移 */
.box { transform: translateZ(100px); } /* 沿Z轴(向屏幕外) */
.box { transform: translate3d(10px, 20px, 30px); }3.5 Transform + Transition 实战
css
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-10px) scale(1.02); /* 悬停时上浮 + 微放大 */
}
.button:hover {
transform: scale(1.05); /* 按钮悬停微放大 */
}
.icon:hover {
transform: rotate(360deg); /* 图标悬停旋转一圈 */
transition: transform 0.6s ease-in-out;
}四、🎬 Animation(关键帧动画)
4.1 两步创建动画
第一步:定义关键帧(@keyframes)
css
@keyframes slideIn {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}第二步:应用动画
css
.element {
animation: slideIn 0.5s ease-out;
}4.2 Animation 子属性
| 属性 | 说明 | 常用值 |
|---|---|---|
animation-name | 关键帧名称 | slideIn |
animation-duration | 持续时间 | 0.5s、2s |
animation-timing-function | 速度曲线 | ease、linear |
animation-delay | 延迟 | 0s、1s |
animation-iteration-count | 重复次数 | 1、3、infinite |
animation-direction | 播放方向 | normal、reverse、alternate |
animation-fill-mode | 结束后状态 | none、forwards、backwards、both |
animation-play-state | 播放状态 | running、paused |
4.3 简写语法
css
/* animation: name duration timing delay count direction fill-mode */
.element {
animation: slideIn 0.5s ease-out 0s 1 normal forwards;
}
/* 最常用简写 */
.element {
animation: slideIn 0.5s ease-out forwards;
}4.4 多段关键帧
css
@keyframes rainbow {
0% { background-color: red; }
20% { background-color: orange; }
40% { background-color: yellow; }
60% { background-color: green; }
80% { background-color: blue; }
100% { background-color: purple; }
}
.box {
animation: rainbow 3s linear infinite;
}4.5 实用动画示例
弹跳效果
css
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.icon { animation: bounce 1s ease-in-out infinite; }脉冲效果
css
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.notification { animation: pulse 2s ease-in-out infinite; }淡入
css
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.card { animation: fadeIn 0.6s ease-out forwards; }旋转加载指示器
css
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
width: 40px; height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}五、⚡ 性能优化
5.1 高性能属性
浏览器对以下属性的动画有 GPU 加速,性能最优:
| ✅ GPU 加速(推荐) | ❌ 触发重排(避免) |
|---|---|
transform | width / height |
opacity | margin / padding |
filter | top / left |
font-size |
css
/* ✅ 高性能:使用 transform 移动 */
.box { transform: translateX(100px); }
/* ❌ 低性能:使用 left 移动 */
.box { position: relative; left: 100px; }5.2 will-change 提示
css
.animated-element {
will-change: transform, opacity; /* 提示浏览器准备 GPU 层 */
}不要滥用 will-change
只在确实需要高性能动画的元素上使用。过度使用会消耗大量 GPU 内存。
5.3 尊重用户偏好
css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}六、💡 实践要点
| # | 要点 | 说明 |
|---|---|---|
| 1 | 动画三宝 | transform + opacity + filter 性能最优 |
| 2 | Transition 用于交互 | 悬停、点击、焦点等状态变化 |
| 3 | Animation 用于自动播放 | 加载动画、提示、装饰效果 |
| 4 | 持续时间 ≤ 0.5s | 大多数 UI 过渡 0.2s–0.4s 最佳 |
| 5 | ease-in-out 最自然 | 除非有特殊需求,否则使用此曲线 |
| 6 | 尊重 prefers-reduced-motion | 部分用户对动画敏感 |
| 7 | 避免在 width/height 上做动画 | 用 transform: scale() 代替 |