使用纯 CSS 实现元素高度的过渡(不采用 max-height)

1. 前言

不知大家是否接触过元素高度的过渡,之前呢我是使用 CSS 加 JS 的方式来解决的,就是通过 JS 计算一下要过渡的元素的高度,然后自己给它加上 height 为某一数值。不知大家是如何解决的?

相信大家在做高度过渡时,都会在想为什么无法实现?就比如下面的代码。

html 复制代码
<style>

    .details {
        position: absolute;
        top: 34px;
        left: 0px;
        border-radius: 8px;
        width: 170px;
        height: 0;
        background-color: rgb(112, 232, 253);
        overflow: hidden;
        transition: height 1s;
    }

    .container {
        position: relative;
        display: inline-block;
        padding: 4px 8px;
        border-radius: 8px;
        background-color: rgb(247, 119, 119);
    }

    .container:hover .details {
        height: auto;
    }
</style>

<div class="container">
    <span>hover 元素</span>
    <div class="details">看看您错过了上个月 Google Open Source Live 活动中的哪些精彩内容。了解使用 Istio 观测您的服务、分析流经服务网格的请求等话题!</div>
</div>

实现的效果就是下面的这个样子

2. 实现

可以看到元素的高度无法从 0 过渡到 auto,因为 auto 不是一个数值。

下面我们会讨论一下 max-height 和 transform 来实现它有什么问题。

2.1. max-height 实现的问题

如果我们询问 ChatGPT 来解决这个问题,它大概率就会向你介绍这个方法,但是这个方法并不能很好的解决。下面是使用 max-height 实现的一个效果。

我们通过过渡 max-height 属性来实现这个效果,就是刚开始时过渡元素的 max-height 为 0,当鼠标触发 hover 时,元素的 max-height 属性则过渡到一个比较大的值,例如 1000px。

但是这样有一个缺点,就是鼠标移入时,我们会注意到鼠标刚移入时,元素高度过渡地特别快,感觉就是嗖地一下就完成了过渡;然后还有鼠标移除时,元素的高度并没有立即过渡,因为元素的 max-height 属性此时为 1000px,要从 1000px 过渡到元素的高度,这段距离还要花一段时间,所以感觉上就是元素延迟了一下,再进行过渡。

2.2. transform 实现的问题

当然上面的方法行不通,我们可以再让 ChatGPT 为我们提供其他的解决方法。这个方法大概率也会提供给你。

这个方法的原理就是使用 transform: scale(),即在 scale(0) 和 scale(1) 之间变化,但是这个会压缩元素的内容,如果你认为你能接受,那这个就不是问题。

2.3. grid 网格实现

其实解决元素高度的过渡也很简单,使用 display: grid 就能解决,相信大多数学前端的小伙伴对 grid 了解的并不多,为什么?可能是因为尚硅谷,黑马程序员的课程还没有更新相关的内容吧,哈哈~不知道大家是看尚硅谷还是看的黑马,我是看的 pink 入门的。

话不多说,实现的代码也很简单,下面就给大家完整的代码:

html 复制代码
<style>
    .details {
        position: absolute;
        display: grid;
        grid-template-rows: 0fr;
        top: 34px;
        left: 0px;
        transition: all 2000ms;
    }

    .details .content {
        width: 170px;
        border-radius: 8px;
        background-color: rgb(112, 232, 253);
        overflow: hidden;  
    }

    .container {
        position: relative;
        display: inline-block;
        padding: 4px 8px;
        border-radius: 8px;
        background-color: rgb(247, 119, 119);
    }

    .container:hover .details {
        grid-template-rows: 1fr;
    }
</style>

<div class="container">
    <span>hover 元素</span>
    <div class="details">
        <div class="content">看看您错过了上个月 Google Open Source Live 活动中的哪些精彩内容。了解使用 Istio 观测您的服务、分析流经服务网格的请求等话题!</div>
    </div>
</div>

实现的效果如下:

当然还要注意一点,由于 details 中的元素是文字,所以需要加上一个子元素并具有 overflow: hidden 属性,亲测有效。

如果这篇文章对你有所帮助,还请点个小小的赞~ 谢谢~~

相关推荐
前端老石人33 分钟前
前端网站换肤功能的 3 种实现方案
开发语言·前端·css·html
冴羽yayujs35 分钟前
2026 年的 JavaScript 已经不是你认识的 JavaScript 了
前端·javascript
小灰灰搞电子36 分钟前
PyQt QWebChannel详解-C++与Web页面的无缝双向通信
前端·pyqt
M ? A41 分钟前
你的 Vue v-for,VuReact 会编译成什么样的 React 代码?
前端·javascript·vue.js·经验分享·react.js·面试·vureact
午安~婉41 分钟前
Electron桌面应用(续3)
前端·javascript·electron·重构通用模型·异步可迭代对象
W.A委员会42 分钟前
伪类与伪元素
前端·javascript·css
午安~婉42 分钟前
Electron桌面应用(续2)
前端·javascript·electron·路由守卫·优化llm返回的内容
eEKI DAND1 小时前
一个比 Nginx 还简单的 Web 服务器
服务器·前端·nginx
Highcharts.js8 小时前
Highcharts 云端渲染的真相:交互式图表与服务器端生成的边界
前端·信息可视化·服务器渲染·highcharts·图表渲染
zhuyan1089 小时前
Linux 系统磁盘爆满导致无法启动修复指南
前端·chrome