过渡

CSS 播客 - 044:过渡

在与网站互动时,您可能会注意到许多元素都有状态。例如,下拉菜单可以处于打开或关闭状态。按钮在获得焦点或悬停时可能会更改颜色。模态窗口会显示和消失。

默认情况下,CSS 会立即切换这些状态的样式。

使用 CSS 过渡,我们可以在元素的初始状态和目标状态之间进行插值。两者之间的过渡通过提供视觉方向、支持以及关于交互的因果关系的提示来增强用户体验。

过渡属性

浏览器支持

  • Chrome: 26.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

来源

要在 CSS 中使用过渡,您可以使用各种过渡属性或 transition 简写属性。

transition-property

transition-property 属性指定要过渡的样式。

.my-element {
  transition-property: background-color;
}

transition-property 接受一个或多个 CSS 属性名称,以逗号分隔的列表形式表示。

或者,您可以使用 transition-property: all 来指示应过渡每个属性。

transition-duration

transition-duration 属性用于定义过渡完成所需的时间长度。

transition-duration 接受时间单位,以秒 (s) 或毫秒 (ms) 为单位,默认值为 0s

transition-timing-function

使用 transition-timing-function 属性在 transition-duration 期间改变 CSS 过渡的速度。

默认情况下,CSS 将以恒定速度过渡您的元素 (transition-timing-function: linear)。然而,线性过渡最终看起来可能有些人工化:在现实生活中,物体具有重量,不能立即停止和启动。缓入或缓出过渡可以使您的过渡更加生动自然。

我们的 CSS 动画模块对时序函数有很好的概述。

您可以使用 DevTools 实时尝试不同的时序函数。

Chrome DevTools visual transition timing editor.

transition-delay

使用 transition-delay 属性指定过渡开始的时间。如果未指定 transition-delay,则过渡将立即开始,因为默认值为 0s。此属性接受时间单位,例如秒 (s) 或毫秒 (ms)。

此属性对于交错过渡非常有用,通过为组中的每个后续元素设置更长的 transition-delay 来实现。

transition-delay 也可用于调试。将延迟设置为负值可以使过渡在时间轴中更早开始。

简写:transition

与大多数 CSS 属性一样,有一个简写版本。transition 结合了 transition-propertytransition-durationtransition-timing-functiontransition-delay

.longhand {
  transition-property: transform;
  transition-duration: 300ms;
  transition-timing-function: ease-in-out;
  transition-delay: 0s;
}

.shorthand {
  transition: transform 300ms ease-in-out 0s;
}

哪些可以过渡,哪些不能过渡?

在编写 CSS 时,您可以指定哪些属性应具有动画过渡。请参阅 此 MDN 可动画 CSS 属性列表

一般来说,只有可以在其开始状态和最终状态之间具有“中间状态”的元素才能过渡。例如,不可能为 font-family 添加过渡,因为不清楚 serifmonospace 之间的“中间状态”应该是什么样子。另一方面,可以为 font-size 添加过渡,因为它的单位是长度,可以在两者之间进行插值。

Diagram of shapes transitioning smoothly from one state to another, and two lines of text in different fonts that cannot be transitioned smoothly.

以下是一些您可以过渡的常用属性。

Transform

浏览器支持

  • Chrome: 36.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

来源

transform CSS 属性通常会进行过渡,因为它是一个 GPU 加速属性,可实现更流畅的动画,同时消耗更少的电池。此属性允许您任意缩放、旋转、平移或倾斜元素。

查看 我们的函数模块关于变换的部分

颜色

在交互之前、期间和之后,颜色可以是状态的绝佳指示器。例如,按钮在悬停时可能会更改颜色。这种颜色变化可以向用户提供按钮可点击的反馈。

colorbackground-colorborder-color 属性只是颜色可以在交互时过渡的几个位置。

查看我们的颜色模块

阴影

阴影通常会过渡以指示海拔高度变化,例如来自用户焦点。

查看我们的阴影模块

滤镜

filter 是一个强大的 CSS 属性,可让您动态添加图形效果。在不同的 filter 状态之间进行过渡可以产生一些非常令人印象深刻的结果。

查看我们的滤镜模块

过渡触发器

您的 CSS 必须包含状态更改触发该状态更改的事件,才能激活 CSS 过渡。此类触发器的典型示例是 :hover 伪类。当用户使用光标悬停在元素上时,此伪类会匹配。

以下是一些伪类和事件的列表,它们可以触发元素中的状态更改。

  • :hover:如果光标在元素上方,则匹配。
  • :focus:如果元素获得焦点,则匹配。
  • :focus-within:如果元素或其任何后代获得焦点,则匹配。
  • :target:当当前 URL 的 片段与元素的 ID 匹配时,则匹配。
  • :active:当元素被激活时(通常在鼠标按在其上方时)匹配。
  • 来自 JavaScript 的 class 更改:当元素的 CSS class 通过 JavaScript 更改时,CSS 将过渡已更改的符合条件的属性。

进入或退出的不同过渡

通过在悬停/焦点时设置不同的 transition 属性,可以创建一些有趣的效果。

.my-element {
  background: red;

  /* This transition is applied on the "exit" transition */
  transition: background 2000ms ease-in;
}

.my-element:hover {
  background: blue;

  /* This transition is applied on the "enter" transition */
  transition: background 150ms ease;
}

无障碍功能注意事项

CSS 过渡并非适用于所有人。对于某些人来说,过渡和动画可能会导致晕动病或不适。值得庆幸的是,CSS 具有一个名为 prefers-reduced-motion 的媒体功能,它可以检测用户是否已指示偏好从其设备减少运动。

/*
  If the user has expressed their preference for
  reduced motion, then don't use transitions.
*/
@media (prefers-reduced-motion: reduce) {
  .my-element {
    transition: none;
  }
}

/*
  If the browser understands the media query and the user
  explicitly hasn't set a preference, then use transitions.
*/
@media (prefers-reduced-motion: no-preference) {
  .my-element {
    transition: transform 250ms ease;
  }
}

请查看我们的博客文章prefers-reduced-motion:有时少即是多,以获取有关此媒体功能的更多信息。

性能注意事项

在使用 CSS 过渡时,如果您为某些 CSS 属性添加过渡,则可能会遇到性能问题。例如,当诸如 widthheight 之类的属性更改时,它们会将内容推送到页面其余部分。这迫使 CSS 为过渡的每一帧计算每个受影响元素的新位置。如果可能,我们建议改用诸如 transformopacity 之类的属性。

请查看我们的关于高性能 CSS 动画的指南,以深入了解此主题。

检查您的理解情况

测试您对过渡的知识

哪个过渡属性用于指定缓动?

transition-duration
请重试。
transition-easing
不是真实的 CSS 属性。
transition-cubic-bezier
不是真实的 CSS 属性。
transition-timing-function
正确!
animation-ease
不是真实的 CSS 属性。

最佳实践是使用 transition-property: all

true
请重试。指定 all 可能会导致性能问题和意外的过渡。
false
正确。最佳实践是单独指定每个属性。更精细的控制将带来更好的性能和更可预测的结果。

所有属性都可以过渡。

true
请重试。诸如 font-family 之类的属性无法过渡。
false
正确。可以为不兼容的属性指定过渡,但它们将离散地过渡。