🧙♂️ CSS 技巧:从高度 0 过渡到自动!
如果你在 CSS 上折腾了很久,那么很有可能你至少尝试过一次从到... 的转换,结果却发现根本行不通! 😢height: 0
auto
➡️ 幸运的是,今天实际上已经解决了这个问题:它在底层使用CSS Grid ,它非常简单并且运行完美!
让我们从一个实际的例子开始。我构建了一个简单的手风琴面板:
它的 HTML非常简单:
<div class="accordion">
<div class="accordion-title">Hover me!</div>
<div class="accordion-body">
<div>
<p>Lorem ipsum ...</p>
</div>
</div>
</div>
如果将鼠标悬停在手风琴折叠面板上,您会注意到出现了一个下拉菜单。这很酷,但是如果我们想让它以平滑的过渡方式出现呢?
我实际上尝试在之前的 codepen 中通过在属性上添加一点过渡来实现这一点height
:
.accordion-body {
height: 0;
transition: 500ms height ease;
}
.accordion:hover .accordion-body {
height: auto;
}
❌ 不幸的是,这不起作用:正如我之前所说,从height: 0
到 的转换对于 CSS 来说是不可能的。height: auto
🤔 如何解决这个问题?
那么,第一个解决方案可能是将height
属性设置为固定数字,而不是auto
。
这会起作用,但这不是一个很好的方法:为了计算这个固定的数字,我们必须求助于JavaScript,以计算我们的.accordion-body
实际高度......这不是我们真正的目标!
😕 我们还能实现这种效果吗,但只使用 CSS解决方案?
💡确实如此!我们为什么不直接用max-height
呢?
.accordion-body {
max-height: 0;
transition: 500ms max-height ease;
}
.accordion:hover .accordion-body {
max-height: 200px;
}
结果如下:
由于我们为定义了一个固定值max-height
,因此浏览器现在能够正确执行转换。
😕唯一的问题是,由于我们为 定义了一个固定值max-height
,现在内容可能会溢出:
如果你确定你的内容永远不会达到某个高度……那么使用这个方法完全没问题!只需为 指定一个合适的值max-height
,就可以了。
但请注意,的值越高max-height
,转换就越奇怪(尝试在之前的代码笔中放入max-height: 1000px
,看看事情如何变化!)。
🤔我们可以做得更好吗?我们可以从一开始就避免出现任何固定的height
/吗?max-height
🎉 CSS Grid 来救援!
✅ 我们实际上可以使用一个巧妙的技巧,该技巧基本上包括使用单个网格项来制作CSS 网格。
我们真正要做的就是将我们的grid-template-rows
高度从 过渡0fr
到1fr
:这样,我们的网格项就会从 0 过渡到它的“自然”高度。就这么简单:
.accordion-body {
display: grid;
grid-template-rows: 0fr;
transition: 250ms grid-template-rows ease;
}
.accordion:hover .accordion-body {
grid-template-rows: 1fr;
}
.accordion-body > div {
overflow: hidden;
}
感觉简洁多了。没有固定高度,没有花哨的东西,折叠面板一切正常。太棒了! 😄
此解决方案的一个缺点是,为了使其正常工作,您实际上需要将 设置overflow: hidden
为.accordion-body
的内部div
。在我看来,这个额外的 CSS 非常值得,但请在评论中告诉我你的想法!
🎁额外提示
此技巧之所以有效,是因为其可动画性(更一般地说,是网格轨道的可动画性)。grid-template-rows
对于某些浏览器来说,这是一个相当新的功能:如果您访问此页面,您会注意到网格轨道动画功能仅在Chrome 107 版之后才出现。
在我撰写本文时,所有主流浏览器都支持此功能,但如果您想在生产代码中使用此功能,请务必先检查兼容性!
就这样!欢迎留言告诉我,你是否已经了解这个超棒的 CSS 功能!😉
下次再见!👋
文章来源:https://dev.to/francescovetere/css-trick-transition-from-height-0-to-auto-21de