前言

在实践过程中遇到一个需求:高度设置为 auto 的元素如何实现高度变化的过渡动画

简单点来说,假设一个场景: 我们把鼠标 hover 一个元素,会弹出一个类似 tooltips 的文字进行说明,而我们希望这个 tooltips 是以一种下滑动画的形式展示出来的

但是我们可能不知道这个 tooltips 元素所占的高度,比如一堆文字放进一个 div 中,这堆文字所占的高度可能就和 div 的宽度、文字大小有关。那么我们该如何实现这种高度扩展/收缩的过渡动画

我们脑子里第一时间可能会想到 CSS transition 可以实现,确实如此,我们这个需求还是基于 transition 来实现。但是当你阅读了 CSS 官方文档或者说自己写下下面这段代码并测试时

1
transition: height 1s ease-in-out 0s;

你可能会发现, CSS 对于 height 设置为 auto 的元素,是不会触发 transition 过渡动画的。正如官方文档中写道:

height :yes, as a length, percentage or calc();

height 的过渡动画仅适用于值是 length,百分比或 calc() 时支持CSS3过渡。

那么我们该怎么办呢?下面我将用一个较为巧妙的方式实现这个需求。

实现原理

既然 height: auto 的元素不能触发过渡动画,那么我们就不设置 height 的高度动画,我们可以巧用 max-heightoverflow:hidden 属性来实现

max-height 顾名思义,就是最大高度,它只是限制元素的最大高度,而当容器的实际高度没有达到 max-height,则不会继续变高。

overflow:hidden 就是将溢出的内容给隐藏掉,即如果内容超过元素的 max-height,多余的内容将会被隐藏。

举例实现

既然已经有了上面的铺垫,那我们就开始动手实现吧!

我们的实验例子就跟上面假设的场景一样,即:提供一个按钮,当 hover 时将下滑出类似 tooltips 的说明文字。

教学文章为方便阅读和理解,只用简单的例子实现。更加复杂的事例其实现原理类似,读者可以自行研究并体会。

首先我们基于 CSS 写下按钮样式 .myButton 和提示文字的样式 .tooltips。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
.myButton {
position: relative;
cursor: pointer;
height: 20px;
width: 120px;
line-height: 20px;
text-align: center;
color: black;
background-color: lightgrey;
border: 1px solid black;
border-radius: 5px;
}

.tooltips 的 CSS 样式中最关键的代码为最后三行,分别对应了:

  1. 初始 max-height 设置为 0。
  2. overflow: hidden 隐藏溢出内容。
  3. 设置 max-height 的 transition 过渡动画。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.tooltips {
position: relative;
margin-top: 5px;
width: 150px;
line-height: 20px;
font-size: 15px;
font-weight: normal;
font-family: sans-serif;
color: black;
background-color: #ddd;
/* 以下为关键代码 */
max-height: 0;
overflow: hidden;
transition: max-height .5s ease 0s;
}

接着,我们需要给 .myButton 加上 hover 事件:.tooltips 的 max-height 设置为一个合适的值,以保证能够容纳下所有文字

不过设定的 max-height 值也不能太大,如果太大则会出现过渡效果不流畅/卡顿的情况。

如果不知道怎么给同级或子级、父级元素添加 hover 事件请自行参考文章《CSS 中 Hover 选择器如何控制其他元素?》

代码如下:

1
2
3
.myButton:hover +.tooltips {
max-height: 200px; // 关键代码
}

按照上面的流程一步一步实现后,我们就算完成了这个简单的 demo。下面你可以测试一下是否和我们想象的效果一样:

Hover 有惊喜

欢迎来到我的博客!我也很开心你能够来看这篇文章!希望这篇文章能够对你有所帮助!当然你也可以在评论区留下你的足迹。

总结

本文采用了一个比较 ”巧” 的方式实现了 height:auto 元素的高度过渡动画,即利用 max-height 结合 overflow: hidden属性。然而,这种方法也存在一定的问题:

  1. max-height 值不好估计,太大容易造成动画不流畅,太小容易造成内容显示不完全。
  2. 如果 max-height 在项目里具有其他的用处,可能该方法会受到影响。
  3. 能够快速完成一些简单的需求,但当问题复杂时,使用该方法容易让问题变得更加复杂。(本人亲测)

个人认为或许更好的办法还是:通过 JS 获取元素的实时高度,给 height 赋予确定的值,再利用 height 的 transition 属性来实现过渡动画。 这种方法的适用面更广,对待复杂问题也更加灵活,而对于简单问题则不如本文方法简便。建议灵活变通,视情况而定。


很感谢你能看到这里!谢谢~