CSS 實現(xiàn)超過固定高度后出現(xiàn)展開折疊按鈕
在平時開發(fā)中,經(jīng)常會碰到一些需要判斷高度的場景,比如當超過一定高度后,需要自動出現(xiàn)展開折疊按鈕,如下:
傳統(tǒng)的思路肯定是通過JS去動態(tài)計算容器的高度,但這樣就涉及到加載時機的問題,獲取早了可能元素還沒渲染好,晚了又會有明顯的卡頓感,或者會引起頁面的閃爍。
那有沒有僅通過CSS的方法呢?
當然也是有的!要實現(xiàn)上面這個例子的效果,需要解決以下幾個問題:
- 如何判斷不同的高度?
- 如何在不同的高度下展示隱藏點擊按鈕?
- 如何點擊切換?
花幾分鐘一起看看吧??
一、先思考一下布局
明確來講,CSS現(xiàn)在已經(jīng)有相關方法可以判斷高度了,那就是CSS容器查詢[1]。不過這個特性太高級了,目前幾乎還不能實戰(zhàn),我們這次介紹一種更加傳統(tǒng)的方式。
如何判斷不同的高度?換句話來說,什么樣的布局在不同的高度下會有截然不同的效果?
思考一下:
絕對定位?位置完全固定了,不行。
flex布局?好像也只能控制水平方向上
grid布局?這個水太深,沒來得及研究(可能也行?)
等等,除了以上,還有一個現(xiàn)在都避而不談的浮動布局,為啥現(xiàn)在都很少用了呢,原因在于浮動布局非常脆弱,細小的尺寸變化都能引起整個布局的坍塌。我記得以前用浮動布局的時候,都需要尺寸精確,稍微出一點差錯就導致浮動元素不知道跑哪去了...
既然對尺寸非常敏感,是不是和本文的臨界高度有一定聯(lián)系呢?
沒錯,今天要用到的方式就是浮動布局。
二、浮動布局的奧妙
一步一步,來搭建我們所需要的頁面雛形。
我們先來看一個有趣的現(xiàn)象,這里有一個容器,里面有3個子節(jié)點,分別為A、B、C,其中A左浮動,B、C右浮動。
當橫向空間足夠時,效果是這樣的。
此時,A貼近左邊,B貼近右邊,C貼著B。
如果橫向空間不足,那么C就會換行。
現(xiàn)在C看似好像跑到了B的下方,其實是因為B的高度還沒有超過A。
當B的高度超過A時,那么C會有如下表現(xiàn)。
此時,C貼在B的左側,A的下方。
是不是很神奇?除了浮動布局,沒有什么方法可以實現(xiàn)這樣的效果了吧。??那么,這和本文的例子有什么關系呢?
別急,其實這是一種極端情況,接著往下看。
三、極端情況下的浮動表現(xiàn)
我們可以設置一個極限狀態(tài),比如A的高度充滿容器,B的寬度充滿容器,此時B肯定會掉下來,我們用負的margin讓B仍保持在一行,如下:
此時,B的高度不高于A,所以C仍然是貼在B的下方,并且靠右?,F(xiàn)在讓B的高度超過A,也就是超出容器高度,就變成了這樣。
此時,C位于A的下方。也就是,僅僅因為高度超過了一個臨界值,C就得到了兩種截然不同的位置,如下:
下面是動態(tài)演示(動態(tài)改變B的高度)。
試想一下,把C當做是“展開折疊”按鈕,在這個基礎上挪動一下C的相對位置,移到正下方,是不是就是我們需要的效果了呢?下面的虛線框示意移動后的位置,這樣在視區(qū)范圍內(nèi),虛線框在高度不足時就是不可見的,只有在超過固定高度后才可見,示意如下(觀察虛線框的位置)。
完整 demo 可以查看以下任意鏈接
- float demo (juejin.cn)[2]
- float demo (codepen.io)[3]
- float demo (runjs.work)[4]
整個原理就是這樣了,下面來看具體實現(xiàn)。
四、CSS 具體實現(xiàn)
現(xiàn)在回到最開頭的例子,根據(jù)前面的 demo 原型,可以改造成以下結構。
這里.text就相當于B,.btn就相當于C,至于A完全可以用偽元素::before來代替。
由于有點擊切換的交互,所以需要用到input checkbox,和label關聯(lián)起來,所以結構最終改造成這樣。
然后加點樣式美化一下吧,由于原理和前面是完全一致的,這里就不重復展示具體細節(jié)了。
效果如下:
然后是點擊切換效果,可以用:checked來控制。
這樣就可以控制不同的狀態(tài)了。
還可以加點遮罩,讓點擊處有一種淡出弱化的效果,表示下面還有內(nèi)容。
效果如下:
完整 demo 可以訪問以下任意鏈接
- CSS auto height expansion (juejin.cn)[5]
- CSS auto height expansion (codepen.io)[6]
- CSS auto height expansion (runjs.work)[7]
五、最后總結一下
想不到浮動布局還能實現(xiàn)這樣的功能,總的來說,這是一種成本低廉但需要點想象力的實現(xiàn)方式,適應性和兼容性也都不錯,下面總結一下:
- 布局有很多種,浮動布局比較特殊。
- 浮動布局非常脆弱,細小的尺寸都能引起整個布局的坍塌。
- 超過指定高度后,由于浮動布局引起的坍塌,正好可以區(qū)分兩種情況。
- 通過改變按鈕本身的相對位置,可以讓案例在超出指定高度后才可見。
- 點擊切換可以用input:check和label相關聯(lián)實現(xiàn)。
- 淡出弱化效果可以添加一層蒙版mask,表示下面還有內(nèi)容。
參考資料
[1]CSS容器查詢: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries。
[2]float demo (juejin.cn): https://code.juejin.cn/pen/7201418511582199842。
[3]float demo (codepen.io): https://codepen.io/xboxyan/pen/zYJvxaN。
[4]float demo (runjs.work): ??https://runjs.work/projects/b7e36f3a248144cd。??
[5]CSS auto height expansion (juejin.cn): https://code.juejin.cn/pen/7201418292035059764。
[6]CSS auto height expansion (codepen.io): https://codepen.io/xboxyan/pen/xxawbWd。
[7]CSS auto height expansion (runjs.work): https://runjs.work/projects/5aa0d64cc2d74d09。