彈性佈局(display:flex;)

一、Flex佈局-前言

Flex是Flexible Box的縮寫,意爲”彈性佈局”,用來爲盒狀模型提供最大的靈活性,旨在提供一個更有效地佈局、對齊方式,並且能夠使容器中的子元素大小未知或動態變化情況下仍然能夠分配好子元素之間的空間。

Flex 佈局的主要思想是使父容器能夠調節子元素的寬度/高度(和排列順序),從而能夠最好地填充可用空間(主要是爲了適應所有類型的顯示設備和屏幕尺寸)。flex布容器能夠放大子元素使之儘可能填充可用空間,也可以收縮子元素使之不溢出。

最重要的是,flexbox佈局與方向無關,不同於常規佈局(基於垂直的塊(block)和基於水平的內聯(inline))。 雖然傳統佈局適用於頁面,但它們對於大型或複雜的應用程序佈局來說缺乏靈活性(特別是在改變方向,調整大小,拉伸,收縮等方面)。

注:

  • Flexbox佈局最適合應用程序的組件和小規模佈局,而 Gird 佈局則適用於較大規模的佈局。
  • 設爲Flex佈局以後,子元素的float、clear和vertical-align屬性將失效。

二、 基本概念

採用 Flex 佈局的元素,稱爲 Flex 容器(flex container),簡稱"容器"。它的所有子元素自動成爲容器成員,稱爲 Flex 項目(flex item),簡稱"項目"。

clipboard.png

三、容器的屬性

clipboard.png

display:flex;

clipboard.png

flex-direction

clipboard.png

clipboard.png

justify-content

clipboard.png

space-around 和 space-between 這兩個值的區別不能很直觀的理解。
space-between 是兩端對齊,使每個矩形子元素(flex項)之間的間隔是相等的,但兩端的矩形子元素(flex項)不會和容器之間產生間隔。

space-around 則會在每個矩形子元素(flex項)的兩邊產生一個相同大小的間隔,也就是說兩端的矩形子元素(flex項)和容器之間的間隔大小正好是兩個矩形子元素(flex項)之間間隔大小的一半(每個矩形子元素產生的間隔不會重疊,所以間隔變成兩倍)。

align-items

clipboard.png
(注意 對於 align-items: stretch 來說,必須將每一個矩形子元素(flex項)的高度設置爲 auto,否則 height 屬性將會覆蓋該 stretch)

對於 align-items: baseline 來說,要注意如果去掉段落標籤或者沒內容,矩形子元素(flex項)就會按照每個矩形的底部對齊,如下圖所示:

clipboard.png

爲了更好地演示主軸和交叉軸的區別,讓我們結合 justify-content和align-items,看看在 flex-direction 兩個不同屬性值的作用下,軸心有什麼不同:

clipboard.png

四、項目的屬性

以下6個屬性設置在項目上

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self

4.1 order

order屬性定義項目的排列順序。數值越小,排列越靠前,默認爲0。

.item {
  order: <integer>;
}

clipboard.png

4.2 flex-grow(拉伸)

首先,讓我們將所有的矩形子元素(flex項)設置爲相同的width,120px:

clipboard.png

現在,涉及到名爲 flex-grow 的屬性,其默認值爲 0 。這意味着矩形子元素(flex項)不允許自動佔據容器中剩餘的空間。

這意味着什麼呢?好吧,讓我們嘗試把爲每個矩形子元素(flex項)的flex-grow設置爲1:

clipboard.png
所有矩形子元素(flex項)共同佔據了整個容器的寬度,它們之間的間隔也都是均勻分佈。flex-grow 值覆蓋了 width 值。

然而,關於 flex-grow 令人困惑的是其值實際上意味着什麼呢?flex-grow: 1是什麼意思呢?

嗯,如果設置每個矩形子元素(flex項)的 flex-grow 屬性值爲 999 ,讓我們來看一下效果:

clipboard.png
正如你所看到的,完全一樣。

這是因爲 flex-grow 不是絕對值 – 它是一個相對值。

對於每個矩形子元素(flex項) 來說,重要的不是其 flex-grow 值有多大,而是這個值與其他矩形子元素(flex項) 的 flex-grow 值相比較,相對值有多大。

如果我們將每個矩形子元素(flex項) 設置爲flex-grow: 1,然後調整第 3 個矩形子元素的flex-grow值,那麼我們可以看到改變,如圖:

clipboard.png

要真正理解這裏到底發生了什麼,讓我們快速過一邊簡單的數學知識。

每個矩形子元素(flex項)的 flex-grow 初始值都是 1。如果我們將每個矩形子元素(flex項)的 flex-grow 相加起來,總和爲 6。因此容器的總寬度被平均分成了 6 份。每個矩形子元素(flex項)增長到填充容器可用空間的1/6。

當我們將第 3 個矩形子元素的 flex-grow 設置爲 2 時,容器現在被分成了 7 等份,因爲所有 flex-grow 屬性是:1 + 1 + 2 + 1 + 1 + 1。

第 3 個矩形子元素佔了整個容器空間的 2/7,其他的佔了 1/7。

同理,當設置第 3 個矩形子元素的 flex-grow: 3 的時候,整個容器寬度被分成了 8 等份(1 + 1 + 3 + 1 + 1 + 1),第 3 個矩形子元素佔了 3/8,其他的佔了 1/8。

以此類推。

flex-grow 只和比例相關,如果我們設置第 3 個矩形子元素 flex-grow: 12,其餘每個方塊的 flex-grow: 4;跟第三個設置成 3,其他的設置成 1 得到同樣的效果,見下圖:

clipboard.png

重要的是每個矩形子元素的 flex-grow 與其他矩形子元素成比例的。

最後一點,請記住,就像 flex-basis 一樣,flex-grow 只適用於主軸(main axis)。我們的矩形子元素只會影響寬度,除非我們將 flex-direction設置爲column。

4.3 flex-shrink(收縮)

flex-shrink 正好和 flex-grow 相反,它是決定矩形子元素允許收縮多少的。

它的主要用途是指定哪些 flex項 要縮小,哪些 flex項 不要縮小。默認情況下,每個矩形子元素(flex項)都爲 1 – 這意味着每個矩形子元素將隨着容器收縮而收縮。

讓我們看看實際情況。 在下面的 GIF 中,每個矩形子元素(flex項)的 flex-grow 爲1,所以他們填充滿了整個容器,並且flex-shrink 爲 1,所以他們被允許收縮。

clipboard.png

現在讓我們將第 3 個矩形子元素的 flex-shrink 設置爲 0 。它是禁止收縮,所以它會隨着容器拉伸而拉伸,但是當容器收縮的時候,當其寬度收縮至設置的120px時,它不再允許收縮。

clipboard.png
flex-shrink 的默認值是 1 – 這意味着你的元素默認允許收縮,除非你告訴他們不允許收縮!

同樣, flex-shrink 約爲比例。如果一個矩形子元素的 flex-shrink 爲 6,並且其餘flex-shrink 爲 2,那麼這個矩形子元素隨着容器空間的收縮,將以 3 倍於其他矩形子元素的速度縮小。

注意這裏的措辭:3x(3倍)flex-shrink的矩形子元素將縮小 3倍。這並不是收縮1/3的寬度。

稍後,我們將深入瞭解元素是如何收縮和拉伸的。但首先,讓我們瞭解最後一個屬性,把這些東西都串起來。

4.4 flex-basis

flex-basis屬性定義了在分配多餘空間之前,項目佔據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多餘空間。它的默認值爲auto,即項目的本來大小。

4.5 flex

flex 是 flex-grow,flex-shrink 和 flex-basis 的縮寫 – 所有這些都放在一起。

它的默認值是0(grow),1(shrink)和 auto(basis)。

4.5 align-self

align-self屬性允許單個項目有與其他項目不一樣的對齊方式,可覆蓋align-items屬性。默認值爲auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

clipboard.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章