本文翻譯自 CSS trick: transition from height 0 to auto!,作者:Francesco Vetere, 略有刪改。
如果你在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>
如果你將鼠標懸停在手風琴上,你會注意到有一個下拉菜單出現。效果不錯,但如果我們想要添加一個漂亮的平滑過渡效果呢?
實際上,我在前面演示的效果中的CSS代碼裏面對height屬性上添加了一個小過渡:
.accordion-body {
height: 0;
transition: 500ms height ease;
}
.accordion:hover .accordion-body {
height: auto;
}
不幸的是,從height: 0轉換到height: auto不起作用,正如我之前所説的,是CSS不可能實現的。
🤔如何解決這個問題?
第一個解決方案是將height屬性設置為一個固定的數字,而不是auto。
這是可行的,但它不是一個很好的方法:為了計算這個固定的數字,我們必須求助於JavaScript,以計算我們的.accordion-body實際上有多高。這不是我們的目標。
💡事實上,為什麼不直接用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的值越高,過渡就越奇怪。
🤔我們能做得更好嗎?我們可以避免任何固定的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的可動性,這是一些瀏覽器最近才有的功能。在我寫這篇文章的時候,所有主流的瀏覽器都支持這個特性,但是如果你想在生產代碼中使用這個特性,一定要先檢查兼容性!
看完本文如果覺得有用,記得點個贊支持,收藏起來説不定哪天就用上啦~
專注前端開發,分享前端相關技術乾貨,公眾號:南城大前端(ID: nanchengfe)