在现代网页设计中,用户体验的流畅性至关重要,CSS的transition属性正是实现这一目标的关键工具之一。它能够将网页元素的变换过程变得平滑而自然,避免元素样式瞬间变换、僵硬动画带来的糟糕用户体验。本文将深入探讨transition属性的工作原理、应用场景以及如何通过它来提升网页的交互体验。
基础知识
首先我们通过一个简单的宽度及颜色过渡的例子,了解transition的功能和相关基础知识。
- 不设置
transition时: - 设置
transition后:
<div></div>
div {
width: 150px;
height: 50px;
transition: all 1s linear 0s;
background: red;
}
div:hover {
width: 250px;
background: blue;
}
transition属性文档中详细介绍了其含义:
transition CSS 属性是 transition-property、transition-duration、transition-timing-function 和 transition-delay 的一个简写属性。
- transition-property 指定应用过渡属性的名称。
- transition-duration 以秒或毫秒为单位指定过渡动画所需的时间。默认值为 0s,表示不出现过渡动画。
- transition-timing-function 这个函数会建立一条加速度曲线,在整个 transition 变化过程中,变化速度可以不断改变。
- transition-delay 规定了在过渡效果开始作用之前需要等待的时间。
💡不是所有属性都支持过渡,动画性 CSS 属性文档中对此有做解释。
过渡与用户体验
以笔者最近开发的数据看板为例,如果不增加过渡动画,看板的展开与折叠将会非常突兀:
添加过渡后:
这里笔者为按钮的悬浮置灰和折叠面板的高度都添加了过渡动画,面板会有一个明显的收起动作,而不是瞬间消失。
眼尖的读者可能会发现,面板的收起非常丝滑,但是展开动画比收起动画快了很多,下面笔者会解释原因。
使用技巧与注意事项
过渡属性需要有确定的值
笔者一开始像下面这样,在折叠状态下控制固定高度,展开后自适应高度,但实际上过渡动画没有触发,还是瞬间展开折叠了。
<div class="data-panel" :style="{height: !expandPanel ? '344px' : 'fit-content'}">
.data-panel {
...
transition: max-height 0.3s ease
}
原因: CSS transtion 需要确保元素的初始和目标高度是明确的数值。
那么对于这种展开后高度不确定的折叠面板,就没有办法添加展开过渡动画了吗?非也,max-height可以解决这个问题:
<div class="data-panel" :style="{maxHeight: !expandPanel ? '344px' : '1400px'}">
只要我们将max-height的目标值设置为肯定比展开后的高度要高的一个值,就可以实现上面动图中的效果。
但是为什么会出现展开动画比收起动画快了很多的现象呢?因为这个 0.3s 本身是 344px → 1400px 的动画时间,但实际展开后如果只有 700px,那么动画实际执行的时间就只有 0.15s了。
如果不能接受这个瑕疵,实际使用中可以考虑根据数据手动计算展开后的高度,或者采用其他实现方式。
更多使用场景
鼠标悬浮菜单延迟关闭
在一些网站我们经常会遇到这种菜单,尤其是顶部导航栏上,很容易发生一种尴尬的场景:鼠标从按钮移动到菜单的过程中不小心超出了按钮和菜单的范围,菜单消失了,用户又要重新执行该操作。 假如我们采用如下方式控制菜单弹窗展示:
<div class="dropdown">
<button class="dropbtn">菜单</button>
<div class="dropdown-content">
<a href="#">链接 1</a>
<a href="#">链接 2</a>
<a href="#">链接 3</a>
</div>
</div>
/* 省略其他样式 */
...
.dropdown-content {
display: none;
...
}
.dropdown:hover .dropdown-content {
display: block;
}
diplay 属性是无法控制过渡时间的,如此一来只能通过 js 来控制菜单的展示时间。但我们可以换一种思路:
/* 省略其他样式 */
...
.dropdown-content {
transition: opacity 0.3s;
transition-delay: 1s;
...
}
.dropdown:hover .dropdown-content {
opacity: 1;
transition-delay: 0s;
}
这样当鼠标悬浮触发 hover 状态时,菜单列表会瞬间打开;而当鼠标移出菜单和按钮范围时,菜单会延迟 1s 再消失。