簡(jiǎn)介
我們經(jīng)常聽(tīng)說(shuō)一種布局:Flexbox或者是彈性布局,它的全稱叫做彈性盒子布局(Flexible Box Layout),那么它到底該如何實(shí)現(xiàn)呢?從我們熟悉的 display 屬性開(kāi)始,給元素添加 display: flex,該元素變成了一個(gè)彈性容器(flex container),它的直接子元素變成了彈性子元素(flex item),那么最簡(jiǎn)單的彈性盒子布局就完成了,它具有以下的效果:
1、彈性容器像塊元素一樣填滿可用寬度(注意,這里只是彈性容器,即添加了display: flex的元素),高度由自身內(nèi)容決定,但是彈性子元素不一定填滿其彈性容器的寬度。
2、彈性子元素默認(rèn)是在同一行按照從左到右的順序并排排列。
3、彈性子元素高度相等,該高度由它們的內(nèi)容決定。
當(dāng)然,我們可以手動(dòng)的設(shè)置它們的寬高,但是在Flexbox布局中,彈性是其最突出的屬性,所有一般我們不建議這樣做。在大致了解了它最顯著的作用之后,下面我們來(lái)進(jìn)行細(xì)致深入的學(xué)習(xí)。
基礎(chǔ)概念
Flexbox布局中,有兩根重要的軸線——主軸&副軸,其屬性幾乎都是圍繞著這兩根軸線來(lái)描述的。默認(rèn)情況下,主軸是水平的,它的起點(diǎn)為最左側(cè),終點(diǎn)為最右側(cè),對(duì)應(yīng)的,有一根與之垂直相交的副軸,它的起點(diǎn)是最上側(cè),終點(diǎn)是最下側(cè)。當(dāng)然,這些方向可以改變,我們稍后介紹。

相關(guān)屬性
1、flex-direction 作用:決定主軸的方向(彈性子元素的排列方向)
row(默認(rèn)值):水平,起始在左端
row-reverse:水平,起始在右端
column:豎直,起始在上沿
column-reverse:豎直,起始在下沿

2、flex-wrap 作用:決定直接子元素是否換行以及如何換行
nowrap(默認(rèn)):不換行
wrap:換行,第一行在上方
wrap-reverse:換行,第一行在下方

3、flex-flow
作用:前面兩個(gè)屬性的簡(jiǎn)寫,默認(rèn)值為 row nowrap
4、justify-content 作用:決定彈性子元素在主軸上的對(duì)齊方式
flex-start(默認(rèn)值):左對(duì)齊
flex-end:右對(duì)齊
center:居中
space-between:兩端對(duì)齊,彈性子元素之間的間隔相等
space-around:彈性子元素兩側(cè)的間隔相等,相鄰之間的間隔會(huì)疊加

5、align-content 作用:決定多行/列彈性子元素在交叉軸上的的對(duì)齊方式 (前提是要開(kāi)啟flex-wrap)
stretch(默認(rèn)值):每行元素將會(huì)被拉伸,直至撐滿整個(gè)交叉軸,每行/列之間的間隔相等
flex-start:與交叉軸起點(diǎn)對(duì)齊
flex-end:與交叉軸終點(diǎn)對(duì)齊
center:在交叉軸上居中對(duì)齊
space-between:與交叉軸兩端對(duì)齊,彈性子元素之間的間距相等
space-around:彈性子元素兩側(cè)的間隔相等,相鄰之間的間隔會(huì)疊加

6、flex-items 作用:決定單行/列彈性子元素在交叉軸上的對(duì)齊方式
stretch(默認(rèn)值):如果沒(méi)有設(shè)置高度/高度設(shè)置為auto,那么將撐滿整個(gè)盒子
flex-start、flex-end、center屬性值的效果同上
baseline:項(xiàng)目的第一行文字的基線對(duì)齊(效果如下,紫色是盒子)

7、flex-basis 作用:指定子元素未受flex-grow或flex-shrink影響時(shí)的初始大小
取值:<length>或<percent>,初始值是auto(此時(shí)會(huì)檢查元素是否設(shè)置了width屬性。如果有,則使用 width 的值作為 flex-basis 的值;如果沒(méi)有,則用元素內(nèi)容自身的大小。如果 flex-basis 的值不是 auto,width 屬性會(huì)被忽略)
8、flex-grow 作用:每個(gè)彈性子元素的 flex-basis 值計(jì)算出來(lái)后,它們(加上子元素之間的外邊距)加起來(lái)會(huì)占據(jù)一定的寬度。加起來(lái)的寬度不一定正好填滿彈性容器的寬度,可能會(huì)有留白。多出來(lái)的留白(或剩余寬度)會(huì)按照 flex-grow(增長(zhǎng)因子)的值分配給每個(gè)彈性子元素。
取值:非負(fù),初始值是0(此時(shí)元素的寬度不會(huì)超過(guò)flex-basis的寬度,不參與分配)
示例:flex-grow 的值越大,元素的“權(quán)重”越高,也就會(huì)占據(jù)更大的剩余寬度。一個(gè) flex-grow: 2 的子元素增長(zhǎng)的寬度為 flex-grow: 1 的子元素的兩倍,如下圖

9、lex-shrink 作用: flex-shrink 屬性與 flex-grow 遵循相似的原則。計(jì)算出彈性子元素的初始主尺寸后,它們的累加值可能會(huì)超出彈性容器的可用寬度。如果不用 flex-shrink,就會(huì)導(dǎo)致溢出,每個(gè)子元素的 flex-shrink 值代表了它是否應(yīng)該收縮以及相應(yīng)的收縮比例以防止溢出。(在開(kāi)啟了flex-wrap之后會(huì)忽略此屬性)
取值:非負(fù),初始值為1(為 0 時(shí),不會(huì)縮?。?
效果:
如果元素A的flex-shrink為0,而其他的元素都為0,那么A不會(huì)縮小
如果元素A的flex-shrink為2,元素B的flex-shrink為1,那么A的縮小的部分的長(zhǎng)度是B的縮小部分的長(zhǎng)度的2倍

示例:如下圖:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex-shrink縮放</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
padding: 1em;
}
#content {
display: flex;
width: 500px;
}
#content div {
flex-basis: 120px;
border: 3px solid rgba(0, 0, 0, 0.2);
}
.box {
flex-shrink: 2;
}
.box1 {
flex-shrink: 1;
}
.result {
margin-top: 20px;
}
p {
line-height: 1.5em;
}
</style>
</head>
<body>
<p>容器寬度為 500px, 彈性子元素的flex-basic 是120px</p>
<p>A, B, C 設(shè)置 flex-shrink:2, D 和 E 設(shè)置 flex-shrink:1</p>
<p>根據(jù)js打印輸出可知,A、B、C縮小的長(zhǎng)度是D、E縮小長(zhǎng)度的2倍</p>
<div id="content">
<div class="box" id="A" style="background-color:red;">A</div>
<div class="box" style="background-color:lightblue;">B</div>
<div class="box" style="background-color:yellow;">C</div>
<div class="box1" id="D" style="background-color:brown;">D</div>
<div class="box1" style="background-color:lightgreen;">E</div>
</div>
<div class="result"></div>
<script>
const A = document.getElementById("A");
const A_width = getComputedStyle(A).width;
const D = document.getElementById("D");
const D_width = getComputedStyle(D).width;
const content = document.getElementById("content");
const content_width = getComputedStyle(content).width;
const result = document.querySelector(".result");
result.innerHTML = `A, B, C 縮放之后的長(zhǎng)度是${A_width},<br />
E縮放之后的長(zhǎng)度是${D_width}, <br />
容器寬度是${content_width}`
</script>
</body>
</html>
10、flex 作用:flex-grow、flex-shrink、flex-basis三個(gè)屬性的簡(jiǎn)寫
取值:
單值語(yǔ)法:值必須是以下之一:
一個(gè) <flex-grow> 的有效值:此時(shí)簡(jiǎn)寫會(huì)擴(kuò)展為 flex: <flex-grow> 1 0。
一個(gè)<flex-basis>的有效值:此時(shí)簡(jiǎn)寫會(huì)擴(kuò)展為 flex: 1 1 <flex-basis>。
關(guān)鍵字 none 或者全局關(guān)鍵字(見(jiàn)后面)之一。
雙值語(yǔ)法:
第一個(gè)值必須是一個(gè) flex-grow 的有效值。
第二個(gè)值必須是以下之一:
一個(gè) flex-shrink的有效值:此時(shí)簡(jiǎn)寫會(huì)擴(kuò)展為 flex: <flex-grow> <flex-shrink> 0。
一個(gè) flex-basis 的有效值:此時(shí)簡(jiǎn)寫會(huì)擴(kuò)展為 flex: <flex-grow> 1 <flex-basis>。
三值語(yǔ)法:值必須按照以下順序指定:
一個(gè) flex-grow 的有效值。
一個(gè) flex-shrink 的有效值。
一個(gè) flex-basis 的有效值。
全局關(guān)鍵字
全局關(guān)鍵字:
initial
元素會(huì)根據(jù)自身寬高設(shè)置尺寸。它會(huì)縮短自身以適應(yīng) flex 容器,但不會(huì)伸長(zhǎng)并吸收 flex 容器中的額外自由空間來(lái)適應(yīng) flex 容器。相當(dāng)于將屬性設(shè)置為"flex: 0 1 auto"。
auto
元素會(huì)根據(jù)自身的寬度與高度來(lái)確定尺寸,但是會(huì)伸長(zhǎng)并吸收 flex 容器中額外的自由空間,也會(huì)縮短自身來(lái)適應(yīng) flex 容器。這相當(dāng)于將屬性設(shè)置為 “flex: 1 1 auto”.
none
元素會(huì)根據(jù)自身寬高來(lái)設(shè)置尺寸。它是完全非彈性的:既不會(huì)縮短,也不會(huì)伸長(zhǎng)來(lái)適應(yīng) flex 容器。相當(dāng)于將屬性設(shè)置為"flex: 0 0 auto"。
flex屬性與以往的簡(jiǎn)寫屬性不同,推薦使用簡(jiǎn)寫形式,因?yàn)檫@樣可以盡可能避免多次分開(kāi)書寫導(dǎo)致的布局不一致,并且可以提高對(duì)瀏覽器的兼容性。
<'flex-grow'>
定義 flex 項(xiàng)目的 flex-grow 。負(fù)值無(wú)效。省略時(shí)默認(rèn)值為 1。 (初始值為 0)
<'flex-shrink'>
定義 flex 元素的 flex-shrink 。負(fù)值無(wú)效。省略時(shí)默認(rèn)值為1。 (初始值為 1)
<'flex-basis'>
定義 flex 元素的 flex-basis 屬性。若值為0,則必須加上單位,以免被視作伸縮性。省略時(shí)默認(rèn)值為 0。(初始值為 auto)
采用邏輯推斷的方法,初始值肯定會(huì)從安全性的角度考慮,所以,元素盡量不要隨意放大,所以flex-grow屬性初始為0;容器會(huì)盡量容納下所有的元素,所以flex-shrink屬性初始值為1;為了以元素自身為主導(dǎo),flex-basis初始值為auto。而所謂的默認(rèn)值,是在flex簡(jiǎn)寫的寫法中被省略時(shí)補(bǔ)充的值,以上規(guī)則能夠體現(xiàn)出來(lái)。
11、order 作用:將彈性子元素從兄弟節(jié)點(diǎn)中移動(dòng)到指定位置,覆蓋源碼順序,值越小,位置越靠前
取值:整數(shù),初始值是0
注意:慎重使用,因?yàn)橐曈X(jué)布局與源碼順序差別太大會(huì)影響網(wǎng)站的可訪問(wèn)性。在大多數(shù)瀏覽器里使用 Tab 鍵瀏覽元素的順序與源碼保持一致,如果視覺(jué)上差別太大就會(huì)令人困惑。視力受損的用戶使用的大部分屏幕閱讀器也是根據(jù)源碼的順序來(lái)的。
12、align-self 作用:跟彈性容器的 align-items 屬性效果相同,但是它能單獨(dú)給彈性子元素設(shè)定不同的對(duì)齊方式。
取值與效果:auto 為初始值,會(huì)以容器的 align-items 值為準(zhǔn)。其他值會(huì)覆蓋容器的設(shè)置。align-self屬性支持的關(guān)鍵字與 align-items 一樣:flex-start、flex-end、center、stretch 以及 baseline。