當前位置:
首頁 > 知識 > Flex布局看這篇就足夠了!

Flex布局看這篇就足夠了!

Flex布局看這篇就足夠了!


Flex基本概念

在 flex 容器中默認存在兩條軸,水平主軸(main axis) 和垂直的交叉軸(cross axis),這是默認的設置,當然你可以通過修改使垂直方向變為主軸,水平方向變為交叉軸,這個我們後面再說。

在容器中的每個單元塊被稱之為 flex item,每個項目佔據的主軸空間為 (main size), 佔據的交叉軸的空間為 (cross size)。

這裡需要強調,不能先入為主認為寬度就是 main size,高度就是 cross size,這個還要取決於你主軸的方向,如果你垂直方向是主軸,那麼項目的高度就是 main size。


Flex 容器

首先,實現 flex 布局需要先指定一個容器,任何一個容器都可以被置頂為 flex 布局,這樣容器內部的元素就可以使用 flex 來進行布局。

Flex布局看這篇就足夠了!

分別生成一個塊狀或行內的 flex 容器盒子。簡單說來,如果你使用塊元素如 div,你就可以使用 flex,而如果你使用行內元素,你可以使用 inline-flex。

需要注意的是:當時設置 flex 布局之後,子元素的 float、clear、vertical-align 的屬性將會失效。

有下面六種屬性可以設置在容器上,它們分別是:

  1. flex-direction

  2. flex-wrap

  3. flex-flow

  4. justify-content

  5. align-items

  6. align-conten

flex-direction: 決定主軸的方向(即項目的排列方向)

Flex布局看這篇就足夠了!

默認值:row,主軸為水平方向,起點在左端。

Flex布局看這篇就足夠了!

row-reverse:主軸為水平方向,起點在右端

Flex布局看這篇就足夠了!

column:主軸為垂直方向,起點在上沿

Flex布局看這篇就足夠了!

column-reverse:主軸為垂直方向,起點在下沿

Flex布局看這篇就足夠了!

column-reverse

flex-wrap: 決定容器內項目是否可換行

默認情況下,項目都排在主軸線上,使用 flex-wrap 可實現項目的換行。

Flex布局看這篇就足夠了!

默認值:nowrap 不換行,即當主軸尺寸固定時,當空間不足時,項目尺寸會隨之調整而並不會擠到下一行。

Flex布局看這篇就足夠了!

nowrap

wrap:項目主軸總尺寸超出容器時換行,第一行在上方

Flex布局看這篇就足夠了!

wrap

wrap-reverse:換行,第一行在下方

Flex布局看這篇就足夠了!

wrap-reverse


flex-flow: flex-direction 和 flex-wrap 的簡寫形式

Flex布局看這篇就足夠了!

默認值為: row nowrap,感覺沒什麼卵用,老老實實分開寫就好了。這樣就不用記住這個屬性了。


justify-content:定義了項目在主軸的對齊方式

Flex布局看這篇就足夠了!

建立在主軸為水平方向時測試,即 flex-direction: row

默認值: flex-start 左對齊

Flex布局看這篇就足夠了!

flex-end:右對齊

Flex布局看這篇就足夠了!

center:居中

Flex布局看這篇就足夠了!

space-between:兩端對齊,項目之間的間隔相等,即剩餘空間等分成間隙

Flex布局看這篇就足夠了!

space-around:每個項目兩側的間隔相等,所以項目之間的間隔比項目與邊緣的間隔大一倍

Flex布局看這篇就足夠了!


align-items: 定義了項目在交叉軸上的對齊方式

Flex布局看這篇就足夠了!

建立在主軸為水平方向時測試,即 flex-direction: row

默認值為 stretch 即如果項目未設置高度或者設為 auto,將佔滿整個容器的高度

Flex布局看這篇就足夠了!

假設容器高度設置為 100px,而項目都沒有設置高度的情況下,則項目的高度也為 100px

flex-start:交叉軸的起點對齊

Flex布局看這篇就足夠了!

假設容器高度設置為 100px,而項目分別為 20px, 40px, 60px, 80px, 100px, 則如上圖顯示

flex-end:交叉軸的終點對齊

Flex布局看這篇就足夠了!

center:交叉軸的中點對齊

baseline: 項目的第一行文字的基線對齊

Flex布局看這篇就足夠了!


align-content: 定義了多根軸線的對齊方式,如果項目只有一根軸線,那麼該屬性將不起作用

Flex布局看這篇就足夠了!

當你 flex-wrap 設置為 nowrap 的時候,容器僅存在一根軸線,因為項目不會換行,就不會產生多條軸線。

當你 flex-wrap 設置為 wrap 的時候,容器可能會出現多條軸線,這時候你就需要去設置多條軸線之間的對齊方式了。

建立在主軸為水平方向時測試,即 flex-direction: row, flex-wrap: wrap

默認值為 stretch,看下面的圖就很好理解了.

Flex布局看這篇就足夠了!

從圖可以看出有三條軸線(因為容器寬度有限),當值為 stretch 時會三條軸線平分容器的垂直方向上的空間。

值得注意的是,雖然在每條軸線上項目的默認值也為 stretch,但是由於我每個項目我都設置了高度,所以它並沒有撐開整個容器。如果項目不設置高度的話就會變成下面這樣:

Flex布局看這篇就足夠了!

這個我在前面也有提到(align-items),這裡重點還是理解三條軸線會平分垂直軸上的空間。

flex-start:軸線全部在交叉軸上的起點對齊

Flex布局看這篇就足夠了!

flex-end:軸線全部在交叉軸上的終點對齊

Flex布局看這篇就足夠了!

center:軸線全部在交叉軸上的中間對齊

Flex布局看這篇就足夠了!

space-between:軸線兩端對齊,之間的間隔相等,即剩餘空間等分成間隙。

Flex布局看這篇就足夠了!

space-around:每個軸線兩側的間隔相等,所以軸線之間的間隔比軸線與邊緣的間隔大一倍

Flex布局看這篇就足夠了!

到這裡關於容器上的所有屬性都講完了,接下來就來講講關於在 flex item 上的屬性。


Flex 項目屬性:

有六種屬性可運用在 item 項目上:

  1. order

  2. flex-basis

  3. flex-grow

  4. flex-shrink

  5. flex

  6. align-self

order: 定義項目在容器中的排列順序,數值越小,排列越靠前,默認值為 0

Flex布局看這篇就足夠了!

Flex布局看這篇就足夠了!

在 HTML 結構中,雖然 -2,-1 的 item 排在後面,但是由於分別設置了 order,使之能夠排到最前面。


flex-basis: 定義了在分配多餘空間之前,項目佔據的主軸空間,瀏覽器根據這個屬性,計算主軸是否有多餘空間

Flex布局看這篇就足夠了!

默認值:auto,即項目本來的大小, 這時候 item 的寬高取決於 width 或 height 的值。

當主軸為水平方向的時候,當設置了 flex-basis,項目的寬度設置值會失效,flex-basis 需要跟 flex-grow 和 flex-shrink 配合使用才能發揮效果。

  • 當 flex-basis 值為 0 % 時,是把該項目視為零尺寸的,故即使聲明該尺寸為 140px,也並沒有什麼用。

  • 當 flex-basis 值為 auto 時,則跟根據尺寸的設定值(假如為 100px),則這 100px 不會納入剩餘空間。

flex-grow: 定義項目的放大比例

Flex布局看這篇就足夠了!

默認值為 0,即如果存在剩餘空間,也不放大

Flex布局看這篇就足夠了!

當所有的項目都以 flex-basis 的值進行排列後,仍有剩餘空間,那麼這時候 flex-grow 就會發揮作用了。

如果所有項目的 flex-grow 屬性都為 1,則它們將等分剩餘空間。(如果有的話)

如果一個項目的 flex-grow 屬性為 2,其他項目都為 1,則前者佔據的剩餘空間將比其他項多一倍。

當然如果當所有項目以 flex-basis 的值排列完後發現空間不夠了,且 flex-wrap:nowrap 時,此時 flex-grow 則不起作用了,這時候就需要接下來的這個屬性。


flex-shrink: 定義了項目的縮小比例

Flex布局看這篇就足夠了!

默認值: 1,即如果空間不足,該項目將縮小,負值對該屬性無效。

Flex布局看這篇就足夠了!

這裡可以看出,雖然每個項目都設置了寬度為 50px,但是由於自身容器寬度只有 200px,這時候每個項目會被同比例進行縮小,因為默認值為 1。

同理可得:

如果所有項目的 flex-shrink 屬性都為 1,當空間不足時,都將等比例縮小。

如果一個項目的 flex-shrink 屬性為 0,其他項目都為 1,則空間不足時,前者不縮小。


flex: flex-grow, flex-shrink 和 flex-basis的簡寫

Flex布局看這篇就足夠了!

flex 的默認值是以上三個屬性值的組合。假設以上三個屬性同樣取默認值,則 flex 的默認值是 0 1 auto。

有關快捷值:auto (1 1 auto) 和 none (0 0 auto)

關於 flex 取值,還有許多特殊的情況,可以按以下來進行劃分:

  • 當 flex 取值為一個非負數字,則該數字為 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%,如下是等同的:

Flex布局看這篇就足夠了!

  • 當 flex 取值為 0 時,對應的三個值分別為 0 1 0%

Flex布局看這篇就足夠了!

當 flex 取值為一個長度或百分比,則視為 flex-basis 值,flex-grow 取 1,flex-shrink 取 1,有如下等同情況(注意 0% 是一個百分比而不是一個非負數字)

Flex布局看這篇就足夠了!

當 flex 取值為兩個非負數字,則分別視為 flex-grow 和 flex-shrink 的值,flex-basis 取 0%,如下是等同的:

Flex布局看這篇就足夠了!

當 flex 取值為一個非負數字和一個長度或百分比,則分別視為 flex-grow 和 flex-basis 的值,flex-shrink 取 1,如下是等同的:

Flex布局看這篇就足夠了!

建議優先使用這個屬性,而不是單獨寫三個分離的屬性。

grow 和 shrink 是一對雙胞胎,grow 表示伸張因子,shrink 表示是收縮因子。

grow 在 flex 容器下的子元素的寬度和比容器和小的時候起作用。 grow 定義了子元素的尺寸增長因子,容器中除去子元素之和剩下的尺寸會按照各個子元素的 grow 值進行平分加大各個子元素上。


容器的 flex-wrap 與子項的 flex-shrink、flex-grow

  1. 當 flex-wrap 為 wrap | wrap-reverse,且子項寬度和不及父容器寬度時,flex-grow 會起作用,子項會根據 flex-grow 設定的值放大(為0的項不放大)

  2. 當 flex-wrap 為 wrap | wrap-reverse,且子項寬度和超過父容器寬度時,首先一定會換行,換行後,每一行的右端都可能會有剩餘空間(最後一行包含的子項可能比前幾行少,所以剩餘空間可能會更大),這時 flex-grow 會起作用,若當前行所有子項的 flex-grow 都為0,則剩餘空間保留,若當前行存在一個子項的 flex-grow 不為0,則剩餘空間會被 flex-grow 不為0的子項佔據

  3. 當 flex-wrap 為 nowrap,且子項寬度和不及父容器寬度時,flex-grow 會起作用,子項會根據 flex-grow 設定的值放大(為0的項不放大)

  4. 當 flex-wrap 為 nowrap,且子項寬度和超過父容器寬度時,flex-shrink 會起作用,子項會根據 flex-shrink 設定的值進行縮小(為0的項不縮小)。但這裡有一個較為特殊情況,就是當這一行所有子項 flex-shrink 都為0時,也就是說所有的子項都不能縮小,就會出現討厭的橫向滾動條

  5. 總結上面四點,可以看出不管在什麼情況下,在同一時間,flex-shrink 和 flex-grow 只有一個能起作用,這其中的道理細想起來也很淺顯:空間足夠時,flex-grow 就有發揮的餘地,而空間不足時,flex-shrink 就能起作用。當然,flex-wrap 的值為 wrap | wrap-reverse 時,表明可以換行,既然可以換行,一般情況下空間就總是足夠的,flex-shrink 當然就不會起作用

align-self: 允許單個項目有與其他項目不一樣的對齊方式

單個項目覆蓋 align-items 定義的屬性

默認值為 auto,表示繼承父元素的 align-items 屬性,如果沒有父元素,則等同於 stretch。

Flex布局看這篇就足夠了!

這個跟 align-items 屬性時一樣的,只不過 align-self 是對單個項目生效的,而 align-items 則是對容器下的所有項目生效的。

Flex布局看這篇就足夠了!

容器 align-items 設置為 flex-start,而第三個項目的 align-self 值為 flex-end。

關於 Flex 布局的語法基礎就講到這裡,還不收藏!!!點贊!!!關注!!!


關注「教授學苑」,期待帶給你快樂的開發知識!

Flex布局看這篇就足夠了!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 教授學苑 的精彩文章:

Node之父Ryan Dahl:我不想被定義
HTML必知必會

TAG:教授學苑 |