不定高元素動畫實現(xiàn)方案(上)
前情
最近接了一個需求,需要實現(xiàn)一個列表,列表可展開收起,展開收起需要有一個動畫效果,而列表個數(shù)不定且每項內(nèi)容高度也不固定,所以是一個不定高的收起展開效果,我嘗試了如下幾中方式,最后選擇了我覺得最佳的
通過max-height來實現(xiàn)
其實把高度設(shè)為auto,可以讓元素高度撐開,但是auto是不會有動畫效果的,此時我們可以把max-height設(shè)為一個較大的值,這樣就實現(xiàn)動畫效果了
代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="inner">
<div class="header">header</div>
<ul class="list">
<li>111111111</li>
<li>2222222222</li>
<li>333333333</li>
</ul>
</div>
</div>
</body>
</html>
*{
margin: 0;
padding: 0;
}
.container{
width: 100%;
max-height: 48px;
overflow: hidden;
transition:max-height .4s;
}
.container:hover{
max-height: 111px;
}
.header{
width: 100%;
height: 48px;
background-color: #ccc;
display: flex;
align-items: center;
justify-content: center;
}
.list{
background-color: green;
}
演示地址:https://jsbin.com/cedifocuci/edit?html,css,output

注意:
max-height設(shè)的太高動畫效果會太快,設(shè)的太小又無法適配所有高度,此方案只能說是能解決問題,但是不是最理想的方案
通過Grid布局來實現(xiàn)
通過網(wǎng)絡(luò)布局,一開始設(shè)置grid-template-rows為0fr,這里有一些技巧,如果子元素有內(nèi)容,0fr是不生效的,要給子元素設(shè)置min-height為0;如果初始要有基礎(chǔ)高度,可以設(shè)置min-height為指定高度來實現(xiàn)基礎(chǔ)高度,此處為48px
關(guān)鍵代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="inner">
<div class="header">header</div>
<ul class="list">
<li>Grid111111111</li>
<li>Grid2222222222</li>
<li>Grid333333333</li>
<li>Grid444444444</li>
</ul>
</div>
</div>
</body>
</html>
*{
margin: 0;
padding: 0;
}
.container{
width: 100%;
display: grid;
grid-template-rows: 0fr;
min-height: 48px;
overflow: hidden;
transition:all .4s;
}
.inner{
min-height: 0;
}
.container:hover{
grid-template-rows: 1fr;
}
.header{
width: 100%;
height: 48px;
background-color: #ccc;
display: flex;
align-items: center;
justify-content: center;
}
.list{
background-color: green;
}
演示地址:https://jsbin.com/xasuviputo/edit?html,css,output

注意:
主流瀏覽器都支持,但是部分國內(nèi)瀏覽器還是有很大兼容問題,如果對兼容性有很高要求的話此方案就不合適了,同時如果你有基礎(chǔ)高度,那基礎(chǔ)高度的那一段是沒有動畫效果的

通過clip-path來實現(xiàn)
clip-path又叫CSS裁剪路徑,clip-path 屬性用于創(chuàng)建一個元素的可視區(qū)域,區(qū)域內(nèi)的內(nèi)容會顯示,而區(qū)域外的內(nèi)容則會被隱藏。這個屬性可以用來對元素進行形狀裁剪,實現(xiàn)各種視覺效果
此處使用clip-path:inset()來實現(xiàn),可以傳入四個數(shù)字inset(1 2 3 4),它們的規(guī)則如下圖

關(guān)鍵代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="inner">
<div class="header">header</div>
<ul class="list">
<li>clip-path111111111</li>
<li>clip-path2222222222</li>
<li>clip-path333333333</li>
<li>clip-path444444444</li>
</ul>
</div>
</div>
</body>
</html>
*{
margin: 0;
padding: 0;
}
.container{
width: 100%;
clip-path: inset(0 0 calc(100% - 48px) 0);
overflow: hidden;
transition:all .4s;
}
.container:hover{
clip-path: inset(0 0 0 0);
}
.header{
width: 100%;
height: 48px;
background-color: #ccc;
display: flex;
align-items: center;
justify-content: center;
}
.list{
background-color: green;
}
演示地址:https://jsbin.com/zelopuyuxi/edit?html,css,output

注意:
主流瀏覽器都支持,但是部分國內(nèi)瀏覽器還是有很大兼容問題,如果對兼容性有很高要求的話此方案就不合適了,相比grid此方案不會有基礎(chǔ)高度無過渡效果的問題

小結(jié)
對于做技術(shù)的我們,每天都是提出問題解決問題的一個過程,過程中會嘗試各種方案,因為解決問題的方案千千萬,此篇文章記錄了實現(xiàn)不定高內(nèi)容過渡效果的三種實現(xiàn)方式,怕篇幅太長,此文暫時寫這么多,下篇繼續(xù)……

浙公網(wǎng)安備 33010602011771號