过渡效果是网页交互体验里性价比最高的细节之一:鼠标悬停时按钮颜色缓缓变化,下拉菜单平滑展开,这些效果背后都离不开CSS过渡。而过渡的节奏感,很大程度上取决于两个属性的配合:transition-duration(过渡持续时间)和transition-delay(过渡延迟时间)。前者决定动画播放多久,后者决定动画何时开始。很多过渡效果看起来生硬或者拖沓,问题往往就出在这两个时间参数没有设置合理。

一、transition-duration与transition-delay的基本语法
先看transition-duration。它的作用是定义过渡从起始状态到结束状态所耗费的时间,接受一个时间值,常用单位是秒(s)和毫秒(ms)。例如transition-duration: 0.3s表示过渡在300毫秒内完成。如果不显式设置duration,默认值是0s,也就是变化瞬间完成,看不到任何过渡效果,这是初学者最常踩的坑:明明写了transition属性却看不到动画,原因就是没给持续时间。
再看transition-delay。它定义的是过渡开始前的等待时间。比如transition-delay: 0.2s表示状态变化后先等200毫秒,过渡才开始播放。delay同样支持s和ms两种单位,还支持负值,负延迟会让过渡从中间某个进度开始播放,这个特性在做循环动画或者补偿动画延迟时非常实用。
两者的简写形式可以写在transition属性里,顺序是:属性名、持续时间、延迟时间、时间曲线。注意duration在前、delay在后,顺序不能颠倒,因为两者都是时间值,浏览器靠位置区分含义:
/* 简写:all属性,0.3秒完成,延迟0.1秒开始,缓动函数为ease-out */
.button {
transition: all 0.3s 0.1s ease-out;
}
/* 分开写的形式,效果等价 */
.button {
transition-property: all;
transition-duration: 0.3s;
transition-delay: 0.1s;
transition-timing-function: ease-out;
}二、多值写法与属性的一一对应规则
transition-duration和transition-delay都支持多个值,用逗号分隔,分别对应transition-property中列出的各个属性。这个规则容易被忽视:如果property写了三个属性,而duration只写了一个值,那么这一个值会循环使用于所有属性;如果写了多个值但数量少于属性数量,同样按顺序循环匹配。理解这个循环匹配规则,可以写出很简洁的代码。
举个例子,希望背景色变化快一点、位移变化慢一点,可以这样写:
.card {
transition-property: background-color, transform;
/* 背景色过渡0.2秒,位移过渡0.5秒 */
transition-duration: 0.2s, 0.5s;
/* 背景色无延迟,位移延迟0.1秒 */
transition-delay: 0s, 0.1s;
}
.card:hover {
background-color: #4a90d9;
transform: translateY(-8px);
}delay的另一个经典应用是交错动画(staggered animation)。比如一组列表项依次淡入,只需给每个元素设置不同的延迟时间,就能形成波浪式的入场效果。配合CSS变量,可以用很少的代码实现批量控制:
.list-item {
opacity: 0;
transition: opacity 0.4s ease;
/* 用CSS变量控制每项的延迟,JS或内联样式修改变量即可 */
transition-delay: calc(var(--index) * 0.08s);
}
.list-item.visible {
opacity: 1;
}三、实践中的时间取值建议与常见场景
过渡时间没有绝对标准,但业界有一些经过大量验证的经验区间。界面反馈类过渡(按钮悬停、链接变色、开关切换)建议控制在0.15s到0.3s之间,太快感觉不到,太慢会让人觉得界面迟钝。元素位移、展开收起类过渡建议0.3s到0.5s。大面积的视觉变化(模态框弹出、页面切换)可以用0.5s左右,再长就容易让用户失去耐心。延迟时间则要谨慎使用,纯装饰性的延迟不要超过0.2s,除非是刻意营造的交错效果。
单位的选择上,建议统一使用秒(s)。虽然0.3s和300ms完全等价,但混用两种单位会降低代码可读性。只在需要非常精细控制(比如10ms级别的调整)时才考虑毫秒单位。
还有一个容易混淆的点:transition-delay和鼠标移出时的行为。如果给hover状态设置了延迟,鼠标快速移入移出时会出现反应滞后。更优雅的做法是把delay写在触发前的状态上,或者利用pointer相关伪类控制移入移出的不同节奏:
/* 移入时立即展开,移出时延迟0.3秒再收起 */
.dropdown {
transition: max-height 0.3s ease;
}
.dropdown:hover {
max-height: 300px;
transition-delay: 0.1s; /* 展开时稍作等待 */
}
/* 移出后回到默认规则,delay恢复为0.3s,给人反应时间把鼠标移回去 */
.dropdown {
transition-delay: 0.3s;
}实际项目中,建议把过渡时间定义成全局变量,方便统一调整和维护:
:root {
--transition-fast: 0.15s;
--transition-base: 0.3s;
--transition-slow: 0.5s;
}
.button {
transition: background-color var(--transition-base), transform var(--transition-fast);
}四、性能与兼容性注意事项
过渡的流畅度不仅取决于时间设置,还取决于被过渡的属性。transition-duration设得再合理,如果过渡的是width、height这类触发重排的属性,依然可能掉帧。应优先过渡transform和opacity,它们由合成器处理,性能开销最小。transition-duration和transition-delay本身的兼容性很好,所有现代浏览器包括IE10都完整支持,唯一需要注意的是旧版Safari需要-webkit-前缀的场景已经基本消失,现在可以放心使用无前缀写法。
另外提醒一点,transition和animation是有分工的。简单的状态切换用transition加duration与delay就够了;如果需要循环播放、中间关键帧控制,就应该用animation。不要为了实现复杂动画而堆砌大量的delay,那样代码会变得难以维护。
总结一下:transition-duration控制快慢,transition-delay控制时机,多值写法按顺序循环匹配属性,取值遵循场景化的经验区间,配合CSS变量统一管理。掌握这些要点,基本就能应对绝大多数界面过渡需求,让页面动效既流畅又有节奏感。
transition-durationtransition-delayCSS过渡修改时间:2026-09-09 17:03:11