一回俐、寬/高自適應(yīng)
(1)左(右)側(cè)固定寬度阻肩,剩余內(nèi)容自適應(yīng)
這里主要利用 flex
本身提供的 flex-grow/flex-shrink/flex-basis
屬性寒亥,通過設(shè)置
flex: 0 0 <width>
來使得部分元素寬度固定蜘醋,而另一部分元素通過設(shè)置 flex: <integer> <integer> <width>
來使得它在容器大小變化的時(shí)候胁塞,被拉伸或者壓縮。
例如你需要制作一個(gè)輸入框压语,左側(cè)需要一個(gè)固定寬度的圖標(biāo)啸罢,右側(cè)需要一個(gè)固定寬度的搜索按鈕,中間需要一個(gè)寬度自適應(yīng)固定的輸入框胎食,
flex
就能助你輕松完成扰才。
(2)上(下)固定高度,剩余內(nèi)容自適應(yīng)
這里主要利用 flex-direction
屬性斥季,將主軸改為沿豎直方向训桶,容器內(nèi)成員都將跟隨主軸方向而沿著豎直方向排列,再結(jié)合上面的方式酣倾,使得成員達(dá)到部分成員高度固定舵揭,另一部分高度自適應(yīng)。
(3)圣杯布局
上面我們其實(shí)已經(jīng)看到了“雙飛翼”在內(nèi)的幾種經(jīng)典布局躁锡,如果再結(jié)合前面兩類布局方式午绳,也可以構(gòu)建出非常典型的“圣杯布局”。
粗看上去有點(diǎn)復(fù)雜映之,但實(shí)際上拦焚,非常簡(jiǎn)單。因?yàn)槠鋵?shí)它只是上面的 “上下固定高度杠输、中間自適應(yīng)” + “左右固定寬度赎败,中間自適應(yīng)的”的組合方式。這里需要注意的一點(diǎn)是蠢甲,作為
flex
容器內(nèi)成員的 DOM
元素僵刮,仍舊可以通過設(shè)置 display: flex;
而變成 flex
容器,這是一個(gè)異常強(qiáng)大的模式,利用好這點(diǎn)搞糕,能完成很多復(fù)雜的布局方式勇吊。
二、水平垂直居中
居中是前端布局中的一個(gè)常見問題窍仰,也是面試過程中的一個(gè)經(jīng)常被提及的問題汉规,常見的 text-align: center;
、vertical-align: center
驹吮、line-height: xxxx
针史、margin: xx auto
、負(fù) margin
钥屈、負(fù) translate
悟民、display: table-cell;
等,各種方案各有利弊篷就,一個(gè)熟練的前端射亏,會(huì)根據(jù)其實(shí)際情況去確定具體的居中方案,但具體用法不是我們這里關(guān)注的點(diǎn)竭业,此處不再贅述智润。flex
為我們提供了一種新的解決辦法:
.flex {
display: flex;
justify-content: center;
align-items: center;
}
看上去是不是很簡(jiǎn)單粗暴?
三未辆、流式布局
在商品列表頁之類的頁面窟绷,以瀑布流為代表的流式布局被得到了廣泛應(yīng)用。一般而言咐柜,使用較多的是 display: inline-block;
和 float: left;
兩種方案兼蜈。但不管是哪種方案,都有一定的瑕疵拙友。
(1)display: inline-block 與 float: left;
利用 display: inline-block
为狸,核心代碼大致如下:
<style>
.inline-block li {
display: inline-block;
}
.left {
overflow: hidden;
}
.left li {
float: left;
}
</style>
......
<div class="container">
<h1>display: inline-block</h1>
<ul class="inline-block">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="container">
<h1>float: left;</h1>
<ul class="left">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
不難發(fā)現(xiàn),使用 display: inline-block
方式生成的流式布局遗契,元素之間形成了一小塊白色空隙辐棒,這是由于我們的 li
標(biāo)簽之間的空格、換行之類的空白符牍蜂,在 li
被設(shè)置成塊級(jí)行內(nèi)元素的時(shí)候漾根,以一個(gè)空格的形式展示到了頁面上,略微嘗試一下鲫竞,你甚至可以選中辐怕、復(fù)制它。盡管你可以在父級(jí)元素上設(shè)置 font-size: 0;
清除掉它从绘,但內(nèi)部元素又會(huì)受到影響秘蛇,你又不得不在內(nèi)層元素上其做,將 font-size
屬性給重置回去顶考,這顯然不是我們樂意見到的赁还。
相比而言,float: left;
方案就沒有上述問題驹沿,而且你還可以通過諸如 overflow: hidden;
以形成 bfc
之類的方式艘策,消除浮動(dòng)對(duì)于正常文檔流帶來的影響≡荆看起來一切都很美好朋蔫,但當(dāng)你嘗試為浮動(dòng)元素之間添加一點(diǎn)間距的時(shí)候,你就會(huì)發(fā)現(xiàn)却汉,問題來了驯妄。
首先是繁瑣的計(jì)算,為了得到合適的寬度合砂,你需要仔細(xì)計(jì)算元素的寬度以及元素之間的間距青扔,切記不要太過相信設(shè)計(jì)師給你的設(shè)計(jì)稿,人艱不拆翩伪。微猖。。其次是當(dāng)你計(jì)算好合適的尺寸之后缘屹,信心滿滿地將 CSS
寫上去的時(shí)候凛剥,你可能面對(duì)兩種情況(假設(shè)這里的間距是使用的 margin-right 添加上去的):
a. 理應(yīng)出現(xiàn)在每行最后的一個(gè)元素,換到下一行去了轻姿。
出現(xiàn)這種情況意味著你在計(jì)算容器寬度的時(shí)候犁珠,可能忘記了考慮每行最后一個(gè)元素的右側(cè)邊距,結(jié)果導(dǎo)致一行元素需要需要占據(jù)的寬度的總和互亮,超過了容器的寬度犁享,最后一個(gè)元素就自然被“擠”到下一行去了。
b.每一行都正確排列胳挎,但仔細(xì)看你會(huì)發(fā)現(xiàn)饼疙,貌似整個(gè)布局稍微往左偏了一點(diǎn)。
出現(xiàn)這種情況意味著你在計(jì)算容器寬度的時(shí)候慕爬,考慮了每一個(gè)元素自身的寬度和右側(cè)邊距窑眯,但這樣其實(shí)相當(dāng)于為容器添加了一定的右側(cè)內(nèi)邊距,容器內(nèi)的元素自然就會(huì)產(chǎn)生一點(diǎn)向左移動(dòng)了的效果医窿。
上面兩種問題磅甩,都有一定的方式去解決,但是一旦你這樣做了姥卢,你的方案就變復(fù)雜了卷要,就像上面使用 font-size
去解決空格帶來的空隙一樣渣聚,這都不是我們?cè)敢饪吹降摹?/strong>不過如果你有興趣,可以去嘗試一下不同的解決方案僧叉,畢竟它們的兼容性還是不錯(cuò)的奕枝,在 pc 站點(diǎn)上都還有著廣泛的應(yīng)用。
(2)flex
的方式
相比于上面提到的方式瓶堕,flex
的實(shí)現(xiàn)方案則顯得更加簡(jiǎn)單隘道、優(yōu)雅。
相比而言郎笆,
flex
方式谭梗,只需要在 flex
容器上設(shè)置 justify-content
設(shè)置成對(duì)應(yīng)的 normal
/space-between
/space-around
/space-evenly
,即可實(shí)現(xiàn)上圖中的效果(后面三個(gè)布局需要容器內(nèi)放滿該行元素之后宛蚓,需要一定剩余位置激捏,且這個(gè)剩余位置一定比下一行第一個(gè)元素窄,否則下一行第一個(gè)元素可能會(huì)補(bǔ)上來)凄吏。最令人驚喜的是远舅,如果你設(shè)置了 flex-direction: column;
,你還能得到如下圖所示效果:此外竞思,結(jié)合
align-content
表谊,flex
還賦予了你操作行與行之間排列關(guān)系的能力:四、柵格(grid)布局
曾經(jīng)嘗試過使用 float 完成過一個(gè)簡(jiǎn)易版的柵格布局盖喷,比這在這里也使用 flex
完成了一個(gè)爆办,相比于使用 float
確實(shí)簡(jiǎn)單得多,有興趣可以嘗試一下课梳。
.grid {
display: flex;
}
li {
flex: 1;
}
.item-full {
flex: 0 0 100%;
}
.item-1of2 {
flex: 0 0 50%;
}
.item-1of3 {
flex: 0 0 33.3333%;
}
.item-1of4 {
flex: 0 0 25%;
}
.item-1of5 {
flex: 0 0 20%;
}
.item-1of6 {
flex: 0 0 16.6666%;
}
......
<ul class="grid">
<li class="item-full">100%</li>
<li class="item-1of2">1/2</li>
<li class="item-1of2">1/2</li>
<li class="item-1of3">1/3</li>
<li class="item-1of3">1/3</li>
<li class="item-1of3">1/3</li>
<li class="item-1of2">1/2</li>
<li class="item-1of3">1/3</li>
<li class="item-1of6">1/6</li>
<li class="item-1of4">1/4</li>
<li class="item-1of2">1/2</li>
<li class="item-1of4">1/4</li>
</ul>