很多內(nèi)容...
很多內(nèi)容...
新聞中心
在平時(shí)開發(fā)中,經(jīng)常會(huì)碰到一些需要判斷高度的場景,比如當(dāng)超過一定高度后,需要自動(dòng)出現(xiàn)展開折疊按鈕,如下:

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比杭州網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式杭州網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋杭州地區(qū)。費(fèi)用合理售后完善,十多年實(shí)體公司更值得信賴。
傳統(tǒng)的思路肯定是通過JS去動(dòng)態(tài)計(jì)算容器的高度,但這樣就涉及到加載時(shí)機(jī)的問題,獲取早了可能元素還沒渲染好,晚了又會(huì)有明顯的卡頓感,或者會(huì)引起頁面的閃爍。
那有沒有僅通過CSS的方法呢?
當(dāng)然也是有的!要實(shí)現(xiàn)上面這個(gè)例子的效果,需要解決以下幾個(gè)問題:
- 如何判斷不同的高度?
- 如何在不同的高度下展示隱藏點(diǎn)擊按鈕?
- 如何點(diǎn)擊切換?
花幾分鐘一起看看吧
一、先思考一下布局
明確來講,CSS現(xiàn)在已經(jīng)有相關(guān)方法可以判斷高度了,那就是CSS容器查詢[1]。不過這個(gè)特性太高級(jí)了,目前幾乎還不能實(shí)戰(zhàn),我們這次介紹一種更加傳統(tǒng)的方式。
如何判斷不同的高度?換句話來說,什么樣的布局在不同的高度下會(huì)有截然不同的效果?
思考一下:
絕對(duì)定位?位置完全固定了,不行。
flex布局?好像也只能控制水平方向上
grid布局?這個(gè)水太深,沒來得及研究(可能也行?)
等等,除了以上,還有一個(gè)現(xiàn)在都避而不談的浮動(dòng)布局,為啥現(xiàn)在都很少用了呢,原因在于浮動(dòng)布局非常脆弱,細(xì)小的尺寸變化都能引起整個(gè)布局的坍塌。我記得以前用浮動(dòng)布局的時(shí)候,都需要尺寸精確,稍微出一點(diǎn)差錯(cuò)就導(dǎo)致浮動(dòng)元素不知道跑哪去了...
既然對(duì)尺寸非常敏感,是不是和本文的臨界高度有一定聯(lián)系呢?
沒錯(cuò),今天要用到的方式就是浮動(dòng)布局。
二、浮動(dòng)布局的奧妙
一步一步,來搭建我們所需要的頁面雛形。
我們先來看一個(gè)有趣的現(xiàn)象,這里有一個(gè)容器,里面有3個(gè)子節(jié)點(diǎn),分別為A、B、C,其中A左浮動(dòng),B、C右浮動(dòng)。
A
B
C
.a{
width: 100px;
height: 100px;
float: left;
background-color: cadetblue;
}
.b{
width: 300px;
height: 100px;
float: right;
background-color: coral;
}
.c{
width: 50px;
height: 100px;
float: right;
background-color: darkgreen;
}當(dāng)橫向空間足夠時(shí),效果是這樣的。
此時(shí),A貼近左邊,B貼近右邊,C貼著B。
如果橫向空間不足,那么C就會(huì)換行。
現(xiàn)在C看似好像跑到了B的下方,其實(shí)是因?yàn)锽的高度還沒有超過A。
當(dāng)B的高度超過A時(shí),那么C會(huì)有如下表現(xiàn)。
此時(shí),C貼在B的左側(cè),A的下方。
是不是很神奇?除了浮動(dòng)布局,沒有什么方法可以實(shí)現(xiàn)這樣的效果了吧。那么,這和本文的例子有什么關(guān)系呢?
別急,其實(shí)這是一種極端情況,接著往下看。
三、極端情況下的浮動(dòng)表現(xiàn)
我們可以設(shè)置一個(gè)極限狀態(tài),比如A的高度充滿容器,B的寬度充滿容器,此時(shí)B肯定會(huì)掉下來,我們用負(fù)的margin讓B仍保持在一行,如下:
.a{
width: 50px;
height: 100%;
}
.b{
width;100%;
margin-left: -50px;
}此時(shí),B的高度不高于A,所以C仍然是貼在B的下方,并且靠右。現(xiàn)在讓B的高度超過A,也就是超出容器高度,就變成了這樣。
此時(shí),C位于A的下方。也就是,僅僅因?yàn)楦叨瘸^了一個(gè)臨界值,C就得到了兩種截然不同的位置,如下:
下面是動(dòng)態(tài)演示(動(dòng)態(tài)改變B的高度)。
試想一下,把C當(dāng)做是“展開折疊”按鈕,在這個(gè)基礎(chǔ)上挪動(dòng)一下C的相對(duì)位置,移到正下方,是不是就是我們需要的效果了呢?下面的虛線框示意移動(dòng)后的位置,這樣在視區(qū)范圍內(nèi),虛線框在高度不足時(shí)就是不可見的,只有在超過固定高度后才可見,示意如下(觀察虛線框的位置)。
完整 demo 可以查看以下任意鏈接
- float demo (juejin.cn)[2]
- float demo (codepen.io)[3]
- float demo (runjs.work)[4]
整個(gè)原理就是這樣了,下面來看具體實(shí)現(xiàn)。
四、CSS 具體實(shí)現(xiàn)
現(xiàn)在回到最開頭的例子,根據(jù)前面的 demo 原型,可以改造成以下結(jié)構(gòu)。
這里.text就相當(dāng)于B,.btn就相當(dāng)于C,至于A完全可以用偽元素::before來代替。
由于有點(diǎn)擊切換的交互,所以需要用到input checkbox,和label關(guān)聯(lián)起來,所以結(jié)構(gòu)最終改造成這樣。
很多內(nèi)容...
很多內(nèi)容...
然后加點(diǎn)樣式美化一下吧,由于原理和前面是完全一致的,這里就不重復(fù)展示具體細(xì)節(jié)了。
.content{
width: 400px;
max-height: 200px;
overflow: hidden;
border-radius: 4px;
outline: 2px dashed royalblue;
}
.section{
display: flex;
}
pre{
white-space: pre-wrap;
}
.content::before{
content: '';
width: 100px;
height: 100%;
float: left;
}
.btn{
float: right;
width: 100px;
text-align: center;
position: relative;
left: calc(50% - 50px);
transform: translateY(-100%);
cursor: pointer;
}
.btn::after{
content: '';
display: block;
height: 34px;
background-color: #666;
transition: .2s background-color;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E %3Cpath d='M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z'%3E%3C/path%3E %3C/svg%3E") center/ 24px 24px no-repeat;
}
.btn:hover::after{
background-color: royalblue;
}
.btn::before{
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 34px;
}
.text{
box-sizing: border-box;
width: 100%;
padding: 10px 15px;
float: right;
line-height: 1.5;
margin: 0;
margin-left: -100px;
font-size: 18px;
color: #232323;
}效果如下:
然后是點(diǎn)擊切換效果,可以用:checked來控制。
.content-check:checked+.content{
max-height: fit-content;
}
.content-check:checked+.content .btn{
left: auto;
right: calc(50% - 50px);
}
.content-check:checked+.content .btn::after{
transform: scaleY(-1);
}這樣就可以控制不同的狀態(tài)了。
還可以加點(diǎn)遮罩,讓點(diǎn)擊處有一種淡出弱化的效果,表示下面還有內(nèi)容。
.text{
/* */
-webkit-mask: linear-gradient(red 150px, transparent 200px);
}效果如下:
完整 demo 可以訪問以下任意鏈接
- CSS auto height expansion (juejin.cn)[5]
- CSS auto height expansion (codepen.io)[6]
- CSS auto height expansion (runjs.work)[7]
五、最后總結(jié)一下
想不到浮動(dòng)布局還能實(shí)現(xiàn)這樣的功能,總的來說,這是一種成本低廉但需要點(diǎn)想象力的實(shí)現(xiàn)方式,適應(yīng)性和兼容性也都不錯(cuò),下面總結(jié)一下:
- 布局有很多種,浮動(dòng)布局比較特殊。
- 浮動(dòng)布局非常脆弱,細(xì)小的尺寸都能引起整個(gè)布局的坍塌。
- 超過指定高度后,由于浮動(dòng)布局引起的坍塌,正好可以區(qū)分兩種情況。
- 通過改變按鈕本身的相對(duì)位置,可以讓案例在超出指定高度后才可見。
- 點(diǎn)擊切換可以用input:check和label相關(guān)聯(lián)實(shí)現(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。
分享文章:CSS實(shí)現(xiàn)超過固定高度后出現(xiàn)展開折疊按鈕
瀏覽路徑:http://www.5511xx.com/article/coscdsd.html


咨詢
建站咨詢
