CSS 过渡
过渡(transition)让属性值的变化不再是瞬间突变,而是在一段时间内平滑渐变。只写一行代码,就能给页面带来细腻的交互质感。
transition 四要素
过渡由四个属性控制:
css
.button {
background: #2563eb;
/* 简写:属性 时长 缓动 延迟 */
transition: background 0.2s ease 0s;
}
.button:hover {
background: #1d4ed8;
} 分写形式
css
.element {
transition-property: background, transform;
transition-duration: 0.3s, 0.2s;
transition-timing-function: ease, ease-out;
transition-delay: 0s, 0.1s;
} transition-property — 哪些属性过渡
指定哪些 CSS 属性变化时触发过渡:
css
.box {
transition-property: background;
/* 仅背景色变化时有动画 */
}
.all {
transition-property: all;
/* 所有可过渡的属性都参与(默认值) */
} 使用 all 虽然方便,但会带来性能开销——浏览器需要监听元素的所有属性变化。建议明确指定需要过渡的属性名。
transition-duration — 持续时长
css
.slow { transition-duration: 1s; } /* 1 秒 */
.normal { transition-duration: 200ms; } /* 200 毫秒 */
.fast { transition-duration: 0.15s; } /* 150 毫秒 */ 一般 UI 交互(hover、focus)建议在 150ms~300ms 之间。太慢会让界面感觉迟钝。
transition-timing-function — 缓动函数
控制动画速度曲线:
| 值 | 效果 |
|---|---|
ease | 慢→快→慢(默认,最常用) |
linear | 匀速 |
ease-in | 慢→快 |
ease-out | 快→慢 |
ease-in-out | 慢→快→慢(比 ease 更平滑) |
cubic-bezier(x1, y1, x2, y2) | 自定义贝塞尔曲线 |
css
.button {
transition: transform 0.2s ease-out;
}
.button:hover {
transform: scale(1.05);
} 自定义贝塞尔曲线
css
/* ease 的等价写法 */
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
/* 弹性效果 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); Chrome DevTools 的 Styles 面板中,点击缓动函数旁边的曲线图标可以可视化的编辑贝塞尔曲线。
transition-delay — 延迟
过渡开始前的等待时间:
css
.delayed {
transition: opacity 0.3s ease 0.5s; /* 0.5s 后开始 */
}
/* 利用延迟实现依次出现 */
.item:nth-child(1) { transition-delay: 0s; }
.item:nth-child(2) { transition-delay: 0.1s; }
.item:nth-child(3) { transition-delay: 0.2s; } 哪些属性可以过渡
大部分数值型属性都可以过渡:
width、height、max-width等margin、paddingbackground、border-color、box-shadowopacitytransform(旋转、缩放、位移)color、font-sizefilter(模糊、亮度等)
不可过渡的属性:display、position、font-family、background-image: url(...)(图片切换无过渡)。
transition 简写
css
.element {
/* 单个属性 */
transition: opacity 0.3s ease;
/* 多个属性用逗号分隔 */
transition:
background 0.2s ease,
transform 0.2s ease,
box-shadow 0.3s ease;
} 进场和退场的细节
过渡只在触发时生效,取消触发时也会反向过渡。但你可以为进场和退场设置不同的参数:
css
.button {
background: #2563eb;
/* 退场:慢一点 */
transition: background 0.3s ease;
}
.button:hover {
background: #1d4ed8;
/* 进场:快一点 */
transition: background 0.1s ease;
} 将 hover 状态的 transition 设为更短时长,可以让”进入动画”更快,而”离开动画”保持原有时长。这符合用户直觉——进场干净利落,退场柔和收尾。
性能注意事项
过渡期间浏览器需要重新计算样式、布局和绘制。不同属性的性能开销差异巨大:
| 开销 | 属性 |
|---|---|
| 低(推荐) | opacity、transform |
| 中 | color、background |
| 高(避免) | width、height、margin、left/top |
css
/* ✅ 推荐:用 transform 实现位移 */
.box {
transition: transform 0.3s ease;
}
.box:hover {
transform: translateY(-4px);
}
/* ❌ 避免:用 margin 实现位移 */
.box {
transition: margin 0.3s ease;
}
.box:hover {
margin-top: -4px;
} transform 和 opacity 的过渡只涉及合成(compositing),不需要重排(reflow)和重绘(repaint),性能远优于其他属性。
如果你需要比过渡更复杂的动画——比如多阶段、循环、播放控制等——请使用 CSS 动画(@keyframes + animation)。