Flex彈性盒子布局(display: flex)

簡介

我們經常聽說一種布局:Flexbox或者是彈性布局,它的全稱叫做彈性盒子布局(Flexible Box Layout),那么它到底該如何實現呢?從我們熟悉的 display 屬性開始,給元素添加 display: flex,該元素變成了一個彈性容器(flex container),它的直接子元素變成了彈性子元素(flex item),那么最簡單的彈性盒子布局就完成了,它具有以下的效果:

1、彈性容器像塊元素一樣填滿可用寬度(注意,這里只是彈性容器,即添加了display: flex的元素),高度由自身內容決定,但是彈性子元素不一定填滿其彈性容器的寬度。
2、彈性子元素默認是在同一行按照從左到右的順序并排排列。
3、彈性子元素高度相等,該高度由它們的內容決定。

當然,我們可以手動的設置它們的寬高,但是在Flexbox布局中,彈性是其最突出的屬性,所有一般我們不建議這樣做。在大致了解了它最顯著的作用之后,下面我們來進行細致深入的學習。

基礎概念

Flexbox布局中,有兩根重要的軸線——主軸&副軸,其屬性幾乎都是圍繞著這兩根軸線來描述的。默認情況下,主軸是水平的,它的起點為最左側,終點為最右側,對應的,有一根與之垂直相交的副軸,它的起點是最上側,終點是最下側。當然,這些方向可以改變,我們稍后介紹。


image.png

相關屬性

1、flex-direction 作用:決定主軸的方向(彈性子元素的排列方向)

row(默認值):水平,起始在左端
row-reverse:水平,起始在右端
column:豎直,起始在上沿
column-reverse:豎直,起始在下沿
image.png
2、flex-wrap 作用:決定直接子元素是否換行以及如何換行

nowrap(默認):不換行
wrap:換行,第一行在上方
wrap-reverse:換行,第一行在下方
image.png
3、flex-flow
作用:前面兩個屬性的簡寫,默認值為 row nowrap
4、justify-content 作用:決定彈性子元素在主軸上的對齊方式

flex-start(默認值):左對齊
flex-end:右對齊
center:居中
space-between:兩端對齊,彈性子元素之間的間隔相等
space-around:彈性子元素兩側的間隔相等,相鄰之間的間隔會疊加

image.png
5、align-content 作用:決定多行/列彈性子元素在交叉軸上的的對齊方式 (前提是要開啟flex-wrap)

stretch(默認值):每行元素將會被拉伸,直至撐滿整個交叉軸,每行/列之間的間隔相等
flex-start:與交叉軸起點對齊
flex-end:與交叉軸終點對齊
center:在交叉軸上居中對齊
space-between:與交叉軸兩端對齊,彈性子元素之間的間距相等
space-around:彈性子元素兩側的間隔相等,相鄰之間的間隔會疊加

image.png
6、flex-items 作用:決定單行/列彈性子元素在交叉軸上的對齊方式

stretch(默認值):如果沒有設置高度/高度設置為auto,那么將撐滿整個盒子
flex-start、flex-end、center屬性值的效果同上
baseline:項目的第一行文字的基線對齊(效果如下,紫色是盒子)

image.png
7、flex-basis 作用:指定子元素未受flex-grow或flex-shrink影響時的初始大小
取值:<length>或<percent>,初始值是auto(此時會檢查元素是否設置了width屬性。如果有,則使用 width 的值作為 flex-basis 的值;如果沒有,則用元素內容自身的大小。如果 flex-basis 的值不是 auto,width 屬性會被忽略)

8、flex-grow 作用:每個彈性子元素的 flex-basis 值計算出來后,它們(加上子元素之間的外邊距)加起來會占據一定的寬度。加起來的寬度不一定正好填滿彈性容器的寬度,可能會有留白。多出來的留白(或剩余寬度)會按照 flex-grow(增長因子)的值分配給每個彈性子元素。
取值:非負,初始值是0(此時元素的寬度不會超過flex-basis的寬度,不參與分配)
示例:flex-grow 的值越大,元素的“權重”越高,也就會占據更大的剩余寬度。一個 flex-grow: 2 的子元素增長的寬度為 flex-grow: 1 的子元素的兩倍,如下圖
image.png
9、lex-shrink 作用: flex-shrink 屬性與 flex-grow 遵循相似的原則。計算出彈性子元素的初始主尺寸后,它們的累加值可能會超出彈性容器的可用寬度。如果不用 flex-shrink,就會導致溢出,每個子元素的 flex-shrink 值代表了它是否應該收縮以及相應的收縮比例以防止溢出。(在開啟了flex-wrap之后會忽略此屬性)
取值:非負,初始值為1(為 0 時,不會縮小)

效果:

如果元素A的flex-shrink為0,而其他的元素都為0,那么A不會縮小
如果元素A的flex-shrink為2,元素B的flex-shrink為1,那么A的縮小的部分的長度是B的縮小部分的長度的2倍

image.png

示例:如下圖:


image.png
<!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 設置 flex-shrink:2, D 和 E 設置 flex-shrink:1</p>
  <p>根據js打印輸出可知,A、B、C縮小的長度是D、E縮小長度的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 縮放之后的長度是${A_width},<br />
    E縮放之后的長度是${D_width}, <br />
    容器寬度是${content_width}`
  </script>

</body>

</html>

10、flex 作用:flex-grow、flex-shrink、flex-basis三個屬性的簡寫
取值:

單值語法:值必須是以下之一:
一個 <flex-grow> 的有效值:此時簡寫會擴展為 flex: <flex-grow> 1 0。
一個<flex-basis>的有效值:此時簡寫會擴展為 flex: 1 1 <flex-basis>。
關鍵字 none 或者全局關鍵字(見后面)之一。
雙值語法:
第一個值必須是一個 flex-grow 的有效值。
第二個值必須是以下之一:
一個 flex-shrink的有效值:此時簡寫會擴展為 flex: <flex-grow> <flex-shrink> 0。
一個 flex-basis 的有效值:此時簡寫會擴展為 flex: <flex-grow> 1 <flex-basis>。
三值語法:值必須按照以下順序指定:
一個 flex-grow 的有效值。
一個 flex-shrink 的有效值。
一個 flex-basis 的有效值。

全局關鍵字

全局關鍵字:

initial
元素會根據自身寬高設置尺寸。它會縮短自身以適應 flex 容器,但不會伸長并吸收 flex 容器中的額外自由空間來適應 flex 容器。相當于將屬性設置為"flex: 0 1 auto"。

auto
元素會根據自身的寬度與高度來確定尺寸,但是會伸長并吸收 flex 容器中額外的自由空間,也會縮短自身來適應 flex 容器。這相當于將屬性設置為 “flex: 1 1 auto”.

none
元素會根據自身寬高來設置尺寸。它是完全非彈性的:既不會縮短,也不會伸長來適應 flex 容器。相當于將屬性設置為"flex: 0 0 auto"。

flex屬性與以往的簡寫屬性不同,推薦使用簡寫形式,因為這樣可以盡可能避免多次分開書寫導致的布局不一致,并且可以提高對瀏覽器的兼容性。

<'flex-grow'>
定義 flex 項目的 flex-grow 。負值無效。省略時默認值為 1。 (初始值為 0)

<'flex-shrink'>
定義 flex 元素的 flex-shrink 。負值無效。省略時默認值為1。 (初始值為 1)

<'flex-basis'>
定義 flex 元素的 flex-basis 屬性。若值為0,則必須加上單位,以免被視作伸縮性。省略時默認值為 0。(初始值為 auto)

采用邏輯推斷的方法,初始值肯定會從安全性的角度考慮,所以,元素盡量不要隨意放大,所以flex-grow屬性初始為0;容器會盡量容納下所有的元素,所以flex-shrink屬性初始值為1;為了以元素自身為主導,flex-basis初始值為auto。而所謂的默認值,是在flex簡寫的寫法中被省略時補充的值,以上規則能夠體現出來。

11、order 作用:將彈性子元素從兄弟節點中移動到指定位置,覆蓋源碼順序,值越小,位置越靠前
取值:整數,初始值是0
注意:慎重使用,因為視覺布局與源碼順序差別太大會影響網站的可訪問性。在大多數瀏覽器里使用 Tab 鍵瀏覽元素的順序與源碼保持一致,如果視覺上差別太大就會令人困惑。視力受損的用戶使用的大部分屏幕閱讀器也是根據源碼的順序來的。
12、align-self 作用:跟彈性容器的 align-items 屬性效果相同,但是它能單獨給彈性子元素設定不同的對齊方式。
取值與效果:auto 為初始值,會以容器的 align-items 值為準。其他值會覆蓋容器的設置。align-self屬性支持的關鍵字與 align-items 一樣:flex-start、flex-end、center、stretch 以及 baseline。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容