聊聊 CSS 實現(xiàn)自適應(yīng)導(dǎo)航欄
在移動端應(yīng)用中,經(jīng)常會碰到這樣的導(dǎo)航欄,導(dǎo)航欄左邊通常是一個返回按鈕,中間是標(biāo)題,右邊是工具欄,如下:
圖片
值得注意的是,右側(cè)的工具欄是不固定的,有可能有多個,也有可能沒有,并且中間的標(biāo)題是整體居中的,如果標(biāo)題過長,還能出現(xiàn)省略號,各種適應(yīng)場景如下:
圖片
一、兩種不完美實現(xiàn)
假設(shè)布局是這樣的:
<appbar>
<tool>
<a class="icon back"></a>
</tool>
<h2 class="title">我是標(biāo)題</h2>
<tool class="right">
<a class="link">規(guī)則</a>
</tool>
</appbar>
很多同學(xué)可能會直接用 flex 布局讓標(biāo)題自動填充剩余空間,然后設(shè)置文本居中。
appbar{
display: flex
}
.title{
flex: 1;
text-align: center;
}
這種布局在左右功能區(qū)寬度差不多的時候還好,看著像居中的,一旦右邊的寬度差異很大,就看著不居中了。
圖片
還有一種是絕對定位,可以實現(xiàn)整體居中。
.title{
position: absolute;
left: 0;
right: 0;
text-align: center;
}
但是,一旦文本過長,就會和左右的功能區(qū)發(fā)生重疊,如下:
圖片
那么,有沒有辦法可以同時滿足這兩種情況呢?
下面介紹兩個方法
二、flex 布局實現(xiàn)
還是前面的 flex 布局,相信大家都用過flex:1這樣的屬性,它可以讓子元素平均分配剩余空間。
.item{
flex: 1
}
如果有3個子元素,那么就會平分為3等分。
圖片
如果僅僅設(shè)置左右兩邊的flex:1,中間寬度不設(shè)置,那么中間部分的寬度就自適應(yīng)內(nèi)容寬度,由于兩邊寬度相等,「因此中間的文本看著就是整體居中的」。
圖片
當(dāng)左右空間不足以均分剩余空間時,會自動壓縮另一個空間。
圖片
直到中間部分不足以放下文本內(nèi)容,出現(xiàn)省略號。
圖片
按照這個原理,先將左右兩邊設(shè)置平均分布。
tool{
flex:1;
}
這樣標(biāo)題就是整體居中的了。
圖片
然后,只需要將右邊菜單居右展示就行了,比如用flex中的justify-content。
.right{
display: flex;
justify-content: end;
}
這樣就就可以很輕松的實現(xiàn)文章開頭的效果。
圖片
完整代碼可以查看:
- CSS Appbar flex (juejin.cn)[1]
- CSS Appbar flex (codepen.io)[2]
三、grid 布局實現(xiàn)
grid 布局也能和能輕易的實現(xiàn)這種效果,原理也基本一致。
和flex中的flex:1比較類似的是,grid中也有一個單位也能做到均等分布的效果,那就是1fr。
div{
display: grid;
grid-template-columns: 1fr auto 1fr;
}
這樣3個子容器,中間是自適應(yīng)寬度,左右是自動等分的。
圖片
原理和前面相同,這里就不重復(fù)了,關(guān)鍵實現(xiàn)如下:
appbar{
display: grid;
grid-template-columns: 1fr auto 1fr;
}
.right{
justify-content: end;
}
這樣也能實現(xiàn)我們想要的效果:
圖片
完整代碼可以查看:
- CSS Appbar grid (juejin.cn)[3]
- CSS Appbar grid (codepen.io)[4]
四、總結(jié)一下
這樣一個實用的布局小技巧,你學(xué)到了嗎?下面總結(jié)一下:
- 移動端導(dǎo)航欄一般都是標(biāo)題整體居中的,并且右側(cè)的工具欄是不固定的
- 傳統(tǒng)的標(biāo)題flex自適應(yīng)和絕對定位都有一定的局限性
- 在剩余空間充足情況下, flex:1可以讓左右兩邊布局尺寸相同,這樣中間標(biāo)題看著就是居中的了
- 在剩余空間不足情況下,中間標(biāo)題空間會撐滿剩余空間,超長則出現(xiàn)省略號
- grid 和 flex 原理相同,有一個1fr單位也可以做到均等分布的效果