1、动画基石:CSS过渡(transition)的四大属性详解
说实话,CSS 动画入门,我建议你从 transition 开始。
为什么?因为它最简单,也最实用。你不需要学什么关键帧、贝塞尔曲线那些花里胡哨的东西,只要掌握四个属性,就能让页面「动起来」。我在项目中做过统计,大概 70% 的动效需求,用 transition 就能搞定。
1.1 transition-property:告诉浏览器「你要动哪个」
这个属性说白了就是指定哪些 CSS 属性变化时要产生过渡效果。默认值是 all,也就是所有能过渡的属性都生效。
/* 只让宽度变化时有过渡 */
.element {
transition-property: width;
}
/* 多个属性用逗号隔开 */
.element {
transition-property: width, height, background-color;
}
/* 所有属性都过渡(默认) */
.element {
transition-property: all;
}
注意:不是所有属性都能过渡。比如
display、visibility 这些就不行。我刚开始学的时候踩过这个坑——hover 时想用 display: none 到 block 的过渡,结果发现根本没效果。
我个人习惯是尽量指定具体属性,而不是用 all。为什么呢?因为 all 会监听所有属性变化,性能上会有损耗。你想想看,如果只是宽度变化,何必让浏览器盯着颜色、位置、透明度呢?
1.2 transition-duration:控制「动多久」
这个最简单,就是设定过渡持续的时间。单位是秒(s)或毫秒(ms)。
.element {
transition-duration: 0.3s; /* 300毫秒,最常用的值 */
}
/* 多个属性可以分别设置时长 */
.element {
transition-property: width, height;
transition-duration: 0.3s, 0.6s; /* width 0.3s, height 0.6s */
}
经验之谈:0.3s 是我最常用的时长。太短了(比如 0.1s)用户根本感觉不到,太长了(比如 1s)又会觉得拖沓。当然,如果是大面积的展开收起,0.5s 会更自然。
1.3 transition-timing-function:决定「怎么动」
这个属性最有意思。它控制的是动画的速度曲线。说白了就是:是匀速运动?还是先快后慢?
| 值 | 效果 | 适用场景 |
|---|---|---|
ease |
慢-快-慢(默认) | 大多数场景,最自然 |
linear |
匀速 | 进度条、加载动画 |
ease-in |
慢-快 | 元素离开屏幕 |
ease-out |
快-慢 | 元素进入屏幕 |
ease-in-out |
慢-快-慢(更明显) | 需要强调的过渡 |
cubic-bezier(n,n,n,n) |
自定义曲线 | 高级定制 |
.element {
transition-timing-function: ease-out; /* 进入时快-慢,很舒服 */
}
/* 自定义贝塞尔曲线 */
.element {
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
}
避坑指南:我曾经在做一个卡片翻转效果时,用了
ease-in,结果翻转过程看起来特别「愣」。后来换成 ease-out,感觉就像卡片被轻轻推了一下,自然多了。记住:元素进入用 ease-out,离开用 ease-in。
1.4 transition-delay:控制「什么时候开始动」
这个属性设置过渡开始前的等待时间。默认是 0s,也就是立即开始。
.element {
transition-delay: 0.2s; /* 等200毫秒再开始过渡 */
}
/* 多个属性分别设置延迟 */
.element {
transition-property: width, height;
transition-duration: 0.3s, 0.6s;
transition-delay: 0s, 0.3s; /* width 立即开始,height 等0.3s后开始 */
}
妙用:利用 delay 可以实现「依次出现」的效果。比如列表项逐个显示,每个项延迟 0.1s,看起来就像排队进场一样。我在做导航菜单的下拉效果时经常用这个技巧。
1.5 组合使用:让过渡真正生效
好了,四个属性都讲完了。但光知道单个属性没用,你得把它们组合起来。我习惯用简写形式,一行搞定:
/* 完整写法 */
.element {
transition-property: width;
transition-duration: 0.3s;
transition-timing-function: ease-out;
transition-delay: 0.1s;
}
/* 简写形式(推荐) */
.element {
transition: width 0.3s ease-out 0.1s;
}
/* 多个属性简写 */
.element {
transition: width 0.3s ease-out,
height 0.5s ease-in 0.2s;
}
核心要点:简写顺序是「属性 时长 速度曲线 延迟」。时长是必填项,其他可以省略。省略时使用默认值。
1.6 实战:一个完整的例子
来看一个我实际项目中用过的卡片悬停效果:
.card {
width: 200px;
height: 300px;
background: #f0f0f0;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.3s ease-out,
box-shadow 0.3s ease-out;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
}
这个效果很简单,但很实用。鼠标移上去时,卡片微微上浮,阴影变深。整个过程 0.3 秒,ease-out 让运动看起来像被轻轻托起。嗯,这就是 transition 的魅力——用最少的代码,实现最自然的交互。
重要提醒:transition 只在属性值变化时触发。如果你用 JavaScript 修改样式,记得要触发浏览器的重绘。我遇到过有人用
element.style.width = '200px' 后没效果,就是因为没有触发过渡条件。
最后说一句:transition 是 CSS 动画的基石。你把它玩熟了,后面学 animation 和关键帧就会轻松很多。下一章我们聊聊如何用 transition 实现更复杂的交互效果。