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;
}
注意:不是所有属性都能过渡。比如 displayvisibility 这些就不行。我刚开始学的时候踩过这个坑——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 实现更复杂的交互效果。