2、CSS过渡动画:transition属性详解、触发条件、贝塞尔曲线调优
大家好,我是你们的老朋友。今天我们来聊聊 CSS 过渡动画,也就是 transition 属性。
说实话,CSS 过渡是我在移动端开发中用得最多的动画方案。为什么?因为它简单、高效,而且浏览器对它的优化做得非常好。你不需要引入任何第三方库,几行代码就能让页面“活”起来。
2.1 transition 属性详解
先来看一个最基础的例子。假设你有一个按钮,希望鼠标悬停时背景色渐变:
.btn {
background-color: #4CAF50;
transition: background-color 0.3s ease;
}
.btn:hover {
background-color: #45a049;
}
这段代码里,transition 是一个简写属性。它背后其实包含了四个子属性:
| 子属性 | 说明 | 示例值 |
|---|---|---|
transition-property |
指定哪些属性需要过渡 | all、opacity、transform |
transition-duration |
过渡持续的时间 | 0.3s、500ms |
transition-timing-function |
速度曲线(缓动函数) | ease、linear、cubic-bezier() |
transition-delay |
延迟多久后开始过渡 | 0s、0.1s |
我个人习惯把 transition 拆开来写,这样可读性更好:
.btn {
transition-property: background-color;
transition-duration: 0.3s;
transition-timing-function: ease;
transition-delay: 0s;
}
transition: opacity 0.3s ease, transform 0.5s ease-out;。但要注意,每个属性的持续时间和缓动函数可以不同。
2.2 触发条件
过渡动画不会凭空发生。它需要一个“触发器”。说白了,就是元素的某个属性值发生了变化。
常见的触发条件有这些:
- 伪类触发:
:hover、:focus、:active、:checked等 - JavaScript 动态修改: 通过 JS 改变元素的
style属性或添加/移除 class - 媒体查询变化: 比如屏幕宽度改变时,元素的尺寸或布局发生变化
- 元素状态变化: 比如
:disabled到:enabled
嗯,这里要注意一点:不是所有 CSS 属性都能过渡。比如 display 就不行。为什么?因为 display 是离散的,它没有中间状态。你想想看,一个元素要么显示要么隐藏,不存在“半显示”的状态。
我在项目中遇到过一个问题:想做一个元素从隐藏到显示的淡入效果。一开始我写了 display: none → display: block 配合 opacity 过渡,结果发现完全不生效。后来才意识到,display 变化是瞬间的,浏览器不会给它做过渡。
height: 0 → height: auto 做展开动画,结果发现过渡无效。因为 auto 是一个计算值,浏览器无法插值。正确的做法是用 max-height 来模拟,或者直接用 transform: scaleY()。
2.3 贝塞尔曲线调优
接下来聊聊贝塞尔曲线。这是 transition-timing-function 的核心。
标准预设值有五个:ease、linear、ease-in、ease-out、ease-in-out。但说实话,在移动端开发中,这些预设值往往不够用。你需要自定义贝塞尔曲线。
自定义的语法是 cubic-bezier(x1, y1, x2, y2)。四个参数控制着曲线的形状:
- x1, y1: 第一个控制点的坐标
- x2, y2: 第二个控制点的坐标
举个例子,我想做一个“回弹”效果:
.card {
transform: scale(1);
transition: transform 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
.card:active {
transform: scale(0.95);
}
这个曲线会让元素先缩小,然后略微“过冲”再回弹到目标位置。看起来很有弹性,很自然。
我个人习惯在调试贝塞尔曲线时,用 Chrome DevTools 的“动画”面板。你可以实时拖动控制点,看到曲线变化对动画的影响。这比凭空想象要高效得多。
- 避免使用
ease-in作为入场动画,因为它结束时会突然停止,显得很生硬 - 入场动画推荐
ease-out或自定义的缓出曲线 - 出场动画推荐
ease-in,让元素“加速离开” - 回弹效果用
cubic-bezier(0.68, -0.55, 0.27, 1.55)这类带负值的曲线
你想想看,为什么移动端特别强调缓动函数?因为手机屏幕小,用户对动画的细腻程度要求更高。一个生硬的动画会让人觉得“卡顿”,哪怕帧率是满的。
2.4 实战中的注意事项
最后,分享几个我在实战中总结的经验:
- 性能优先: 尽量只对
opacity和transform做过渡。这两个属性不会触发重排(reflow),性能最好。 - 避免过渡所有属性: 不要用
transition: all 0.3s。这会监听所有属性的变化,性能开销大,而且容易引发意料之外的动画。 - 合理使用延迟:
transition-delay可以用来做“错峰”动画。比如列表项依次出现,每个项延迟 0.1s。 - 注意移动端点击穿透: 如果你用
opacity: 0隐藏元素,记得加上pointer-events: none,否则用户还是能点到它。
好了,关于 CSS 过渡动画,今天就聊到这里。下一节我们会深入 animation 属性,那才是真正的大招。记得动手试试上面的代码,光看是学不会的。