讲解
transition 让属性值的变化「渐变」而不是「突变」:鼠标悬停按钮背景变深,加一行 transition 就有了 0.3 秒的平滑过渡。四个子属性:transition-property(哪些属性参与,如 background-color,或 all)、transition-duration(时长,如 0.3s)、transition-timing-function(速度曲线:ease 默认先快后慢、linear 匀速、ease-in-out、或 cubic-bezier(0.4, 0, 0.2, 1) 自定义)、transition-delay(延迟)。简写 transition: background-color 0.3s ease。
关键心智模型:transition 写在「平时状态」的规则上(不是 :hover 上),它同时管「进入悬停」和「离开悬停」两个方向的动画;写在 :hover 上则只在悬停时生效,鼠标移开会生硬跳回。不是所有属性都能过渡:数值类(尺寸、颜色、透明度、位置)可以,离散类(display、position、font-family)不可以——display: none 到 block 没有中间状态,会直接跳变(现代 CSS 有 transition-behavior: allow-discrete 配合 @starting-style 解决,知道即可)。
性能是过渡的必修课:只有 transform 和 opacity 的变化能全程走 GPU「合成层」,流畅 60fps;过渡 width、height、top、margin 这类布局属性会触发重排重绘,元素多了就掉帧。所以「位移用 transform: translate 而不是改 left、显隐用 opacity 而不是改宽高」是动效开发的铁律。时长上,微交互 150-300ms 最合适,超过 500ms 用户会觉得界面迟钝。
示例
/* 按钮:多属性过渡,写在平时状态上 */
.button {
background: #1c7ed6;
transform: scale(1);
transition:
background-color 0.2s ease,
transform 0.15s ease;
}
.button:hover {
background: #1971c2;
transform: scale(1.05); /* transform 过渡走 GPU,流畅 */
}
/* 卡片悬浮上浮:位移和阴影同时过渡 */
.card {
transition:
transform 0.25s ease,
box-shadow 0.25s ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
}
/* 展开面板:透明度可过渡,高度 auto 不行(见常见坑) */
.panel {
opacity: 0;
visibility: hidden;
transition:
opacity 0.3s ease,
visibility 0.3s; /* 离散属性放在最后「兜底跳变」 */
}
.panel.open {
opacity: 1;
visibility: visible;
}
常见坑
- transition 写在 :hover 上:鼠标移出时动画不生效、样式瞬间跳回。写在元素常态规则里,进出都有动画。
- 过渡 display:none ↔ block 不可过渡,元素直接闪现。用 opacity + visibility 组合,或 transition-behavior: allow-discrete 新方案。
- transition: all 一写了事:all 会把没打算动的属性也纳入监听,性能差且容易产生意外动画。明确列出要过渡的属性。
- 过渡 height: auto:auto 没有数值中间态,过渡失效。现代替代:grid-template-rows 从 0fr 到 1fr 的技巧,或 max-height 给一个偏大的上限(时长相近即可,不完美但常用)。
- 动效过度:满屏元素都在动、时长一秒起步,用户眩晕。微交互 150-300ms,装饰动画克制使用,并尊重 prefers-reduced-motion。
小结
transition 管属性值的渐变,写在常态规则上;能过渡的是数值类属性,transform/opacity 性能最好;150-300ms 是微交互甜区。下一章深入刚才反复用到的 transform。