讲解

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。