CSS实现auto高度的过渡动画

程序员他爱做梦 2024-03-06 23:44:42
问题描述

下面是一个常见的效果,当鼠标悬浮时展开显示内容,离开时自动收回。

<div id="wrapper"> <h4>hover me!</h4> <div id="content"> <p>Hello, World!</p> <p>Hello, World!</p> <p>Hello, World!</p> <p>Hello, World!</p> </div></div>

#wrapper { width: 240px; padding: 16px 24px; border-radius: 12px;}#content p { line-height: 32px;}#content { height: 0; overflow: hidden; /*不起作用*/ transition: height 500ms;}#wrapper:hover #content { height: auto;}

由于通常不知道content中具体内容所占的高度,因此常用height: auto;设置高度。上面的示例可以良好的实现要求,问题出现在当我们需要为这个高度的变化添加过渡动画时,会发现transition: height 200ms;不起作用,这是因为auto并不是一个具体的高度数值。

使用 max-height 解决

一个常见方案是使用max-height控制。这样确实可以实现过渡动画效果,但并不是一个“完美”的动画:当过高的估计了content容器的最大可能高度时,鼠标移入时的动画会的变快,而移出时动画会有延迟。这是因为有一部分时间花在了max-height数值在content容器的真实高度和设定值之间的过渡上,而这部分过渡时间不会影响页面元素的样式。

#wrapper { width: 240px; padding: 16px 24px; border-radius: 12px;}#content p { line-height: 32px;}#content { /*起始高度*/ max-height: 0; overflow: hidden; transition: max-height 500ms;}#wrapper:hover #content { /*确保大于content最大可能高度*/ max-height: 600px;}

更好的方案:使用 grid

一个更完美的解决方案是使用网格布局:

注意在html结构中,要为content再添加一层子元素div,display: grid;和grid-template-rows属性仍然设置给content,但此时overflow: hidden;要设置给content的子元素。

<div id="wrapper"> <h4>hover me!</h4> <div id="content"> <div> <p>Hello, World!</p> <p>Hello, World!</p> <p>Hello, World!</p> <p>Hello, World!</p> </div> </div></div>

#wrapper { width: 240px; padding: 16px 24px; border-radius: 12px;}#content p { line-height: 32px;}#content { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 500ms;}#content > div { /*使子元素动画与父元素保持一致*/ grid-row: 1 / span 2; /*overflow也设置给子元素*/ overflow: hidden;}#wrapper:hover #content { grid-template-rows: 1fr;}

讨论

grid-row: 1 / span 2;这行代码看起来有些费解,因为毕竟只有一行子元素。它的作用是使子元素动画与父元素保持一致。我们把动画放慢,并且给content带上灰色背景,给content > div带上红色背景,观察一下使用和不使用这个属性的区别:

注:这个问题是否发生似乎与浏览器的行为有关:在我测试时,使用Google Chrome和Microsoft Edge时二者表现是不同的,但在Firefox中是相同的,即使不写grid-row: 1 / span 2;也不会引起这个问题。

作者:Suzukii链接:https://juejin.cn/post/7317994541712949282

0 阅读:0

程序员他爱做梦

简介:感谢大家的关注