Hover me
Generated CSS

CSS过渡效果 — 完整参考指南

CSS过渡是前端开发者工具箱中最强大的工具之一。当CSS属性值发生变化时——因为用户悬停在元素上、通过JavaScript切换了类,或输入框获得了焦点——浏览器通常会立即应用这一变化。过渡会拦截这一变化,在定义的持续时间内从旧值动画到新值,无需任何动画JavaScript代码,就能产生流畅、专业的UI反馈。

思维模型很简单:在元素上声明哪些属性应该动画、动画持续多长时间、遵循什么缓动曲线,以及开始前是否有延迟。浏览器会自动处理所有逐帧插值,对于transform和opacity等合成属性使用GPU加速——这就是为什么这两个属性是高性能动画的黄金标准。

transition属性的工作原理

简写属性transition将四个子属性合并为一个声明。你可以通过逗号分隔来针对多个属性,每个逗号分隔的值可以有自己的持续时间、缓动和延迟。这比使用transition: all好得多,后者强制浏览器在每一帧检查每个CSS属性——这是一个性能陷阱。

四个子属性是:transition-property(要动画的CSS值)、transition-duration(持续时间)、transition-timing-function(缓动曲线)和transition-delay(开始前等待时间)。延迟对于交错效果特别有用。

时序函数决定动画个性

如果持续时间决定动画需要多长时间,时序函数决定它的感觉如何。两个持续时间相同但时序函数不同的动画感觉完全不同。ease-out——快速开始后减速——模拟物体到达并停下的物理行为,这就是为什么它在元素进入屏幕时感觉自然。ease-in——缓慢开始后加速——适合元素离开时使用。linear感觉机械,这正是进度条所需要的。

哪些属性可以过渡?

并非所有CSS属性都支持插值。属性必须有浏览器能够计算中间步骤的值。数值、颜色、长度和百分比都可以插值。离散值如displayfont-family则不能。

性能和支持同样重要。浏览器渲染管线有三个阶段:布局、绘制和合成。只有transformopacity完全由GPU合成层处理,这意味着它们以完整帧率动画,对布局或绘制没有影响。

隐藏元素的visibility技巧

最常见的过渡挑战之一是让元素平滑消失。设置display: none会立即将元素从文档中移除——你无法过渡到它或从它过渡。解决方案是将opacityvisibility结合使用。visibility属性接受过渡延迟,所以你可以在透明度淡出完成后再让元素变为不可交互。

使用transition-delay实现交错效果

交错——让多个元素依次动画而不是同时——在UI中创造更动态、更有活力的感觉。技术很简单:对一组元素应用相同的基础过渡,然后使用:nth-child选择器给每个元素逐渐增加transition-delay

负延迟——从动画中途开始

负的transition-delay值告诉浏览器从好像已经运行了那么长时间的位置开始过渡。-300ms的值意味着动画从300ms处开始而不是从0开始。

FLIP技术

FLIP(First、Last、Invert、Play)是一种用于动画布局变化的模式,否则这些变化需要过渡昂贵的属性。你记录元素变化前的位置(First),应用变化(Last),计算差异并以transform的形式应用反转(Invert),然后删除反转让浏览器动画到最终位置(Play)。

性能和will-change

will-change属性是给浏览器的提示,表明某个元素即将动画,让它有机会在动画开始前将该元素提升到自己的GPU合成层。该属性应谨慎使用——每个提升的层都消耗GPU内存。

无障碍性和prefers-reduced-motion

患有前庭障碍、偏头痛或对运动敏感的用户可能会因屏幕动画感到真实的身体不适。操作系统暴露了一个"减少运动"无障碍设置,可通过prefers-reduced-motion媒体查询进行查询。WCAG 2.1成功标准2.3.3要求由交互触发的运动可以被禁用。

过渡 vs CSS动画

过渡和CSS动画解决不同的问题。过渡总是由状态变化触发,并在恰好两个状态之间动画。当状态变化反转时,它们会自动反转。不需要@keyframes声明。CSS动画则可以循环,可以定义多个中间关键帧,可以在页面加载时自动运行。

为什么我的CSS过渡不起作用?

四个最常见的原因:(1) transition声明在hover/active状态而不是基础元素上——基础元素必须声明过渡才能平滑反转。(2) 属性不可插值——display和渐变background-image值不能过渡。(3) 两个状态的计算值相同。(4) transition-duration缺失或默认为0s。

可以过渡background-image渐变吗?

不能——CSS渐变值在技术上是background-image值,图像值不可插值。解决方法:在当前背景后面或上面叠加一个带有新渐变的伪元素,并将其透明度从0过渡到1。

如何让元素从display:none过渡到可见?

你不能——display变化是即时的。将opacityvisibility配合使用,在隐藏方向上为visibility添加匹配的延迟。对于基于高度的折叠,使用max-height: 0过渡到大于内容高度的max-height。

应该使用多长的持续时间?

谷歌Material Design 3指南建议:小组件状态变化100–200ms,中等过渡250–400ms,全屏过渡400–600ms。低于100ms难以察觉。超过500ms对于重复交互开始感觉缓慢。

应该使用过渡还是JavaScript动画库?

CSS过渡非常适合由类或属性变化驱动的离散状态变化——悬停效果、焦点环、切换、抽屉滑动、模态框打开。JavaScript动画库如GSAP或Motion One更适合需要跨多个元素的序列编排、物理模拟或滚动链接动画。

Tool last updated: