title: flex從總結到了解
date: 2021-10-19 17:09:22
tags:
- flex
categories:
- [前端開發, CSS]
author: 輕鬆學英語
flex 是一種佈局方式,在 CSS3 之後開始有。它主要由父容器和子項組成,父容器有六個屬性,分別為:
控制主軸軸向:
flex-direction
- row:橫軸(預設)
- row-reverse:倒過來的橫軸
- column:豎軸
- column-reverse:倒過來的豎軸
換行方式:
flex-wrap
- nowrap:不換行(預設)
- wrap:換行
- wrap-reverse:反著換行
- 主軸排列:
justify-content
- 交叉軸排列:
align-items
軸向與換行組合設定:
flex-flow
(流向)- 一般很少用這個屬性,即改變子項的佈局順序,正著來,倒著來
子項也有六個屬性,分別為:
彈性擴充套件:
flex-grow
- 指定容器剩餘空間多餘時的分配規則
- 預設值為 0,多餘空間不分配
彈性收縮:
flex-shrink
- 指定容器剩餘空間不足時的分配規則
- 預設值為 1,空間不足要分配;如果為 0,表示不分配
基礎尺寸:
flex-basis
- 指定 flex 元素在主軸方向上的初始大小(基礎尺寸)
- 預設值為 auto,即專案本身大小
縮寫:
flex
- flex-grow、flex-shrink、flex-basis 的縮寫
- 預設值為 0 1 auto
- 主軸順序:
order
- 交叉軸對齊方式:
align-self
總的來說,父容器控制整體佈局,子項控制子項佈局
在面試中,常常不會問怎麼寬泛,最常見的 flex 面試題為:
flex: 0 1 auto
怎麼理解?flex: 1
具體代表什麼,有什麼應用場景flex: 0
、flex: 1
、flex: none
、flex: auto
,表示什麼意思,並應用在什麼場景下使用?
要想回答這些問題,我們必須瞭解子項中的 flex 屬性
flex 語法
flex: none | auto | [< 'flex-grow' > < 'flex-shrink' >? || < 'flex-basis' > ];
單管道符 |
,表示排他。也就是這個符號前後的屬性值都是支援的,且不能同時出現。因此,下面這些語法都是支援的:
flex: auto;
flex: none;
flex: [< 'flex-grow' > < 'flex-shrink' >? || < 'flex-basis' >];
方括號 [...]
表示範圍。支援的屬性在這個範圍內
其中 ?
,表示 0 個或者 1 個,也就是說 flex-shrink
屬性可有可無。因為 flex 屬性值也可以是 2 個值
flex: auto;
flex: none;
/* 2個值 */
flex: 1 100px;
/* 3個值 */
flex: 1 1 100px;
雙管道 ||
,表示”或者“的意思。表示前後可以分開獨立使用,也就是 flex: flex-grow flex-shrink?
和 flex-basis
都是合法的。於是我們又多了 2 種合法的寫法:
/* 1個值,flex-basis */
flex: 100px;
/* 2個值,flex-grow 和 flex-shrink */
flex: 1 1;
轉為文字表述
單值語法:
如果 flex 的屬性值只有一個值,有三種情況
一個無單位數,例如例如
flex: 1
,表示flex-shrink: 1
,剩餘空間擴充套件。此時,flex-shrink
和flex-basis
的值分別是 1 和 0%。注意,這裡的flex-basis
的值是 0%,而不是預設值auto
- 只要改變
flex: 數字
,flex-basis
的值就為 0
- 只要改變
- 一個有效的寬度(width)值,表現形式為長度值,例如
flex: 100px
,表示flex-basis: 100px
,基礎尺寸為 100px。此時,flex-grow
和flex-shrink
的值都是 1,注意,這裡的flex-grow
的值是 1,而不是預設值 0 - 關鍵字
none
,auto
或initial
雙值語法:
如果 flex 的屬性值有兩個值,則第 1 個值一定是 flex-grow
,第 2 個根據值的型別不同表示不同的 CSS 屬性,具體規則如下:
- 數值:例如
flex: 1 2
,則這個 2 表示flex-shrink
,此時flex-basis
的值為 0%,而非預設值 auto - 長度值,例如
flex: 1 100px
,則這個100px
值flex-basis
,此時flex-shrink
預設值為 0
三值語法:
如果 flex 的屬性值有 3 個值,則長度值表示 flex-basis
,其餘 2 個數值分別表示flex-grow
和 flex-shrink
。下面兩行 CSS 語句的語法都是合法的,且含義也是一樣的:
flex: 1 2 50%;
flex: 50% 1 2;
flex 屬性值場景應用
flex 預設值為 0 1 auto。除此之外,還有各種其他值
- flex: none,等同於 flex: 0 0 auto;
- flex: auto,等同於 flex: 1 1 auto;
- flex: 1,等同於 flex: 1 1 0%;
- flex: 0,等同於 flex 0 1 0%;
張鑫旭大神畫過一張圖:
單值語法 | 等同於 | 備註 |
---|---|---|
flex: initial | flex: 0 1 auto | 初始值,常用 |
flex: 0 | flex: 0 1 0% | 適用場景少 |
flex: none | flex: 0 0 auto | 推薦 |
flex: 1 | flex: 1 1 0% | 推薦 |
flex: auto | flex: 1 1 auto | 適用場景少 |
預設值 flex: initial
它等同於 flex:0 1 auto
,表示 flex 容器有剩餘空間時尺寸不增長(flex-grow
: 0),flex 容器尺寸不足時尺寸會收縮變小(flex-shrink
:1),尺寸自適應於內容(flex-basis
:auto)
我的理解:子項總長度小於總容器時,不會去撐滿(flex-grow
:0),而按實際寬高度存在(flex-basis
:auto);當子項總長度大於總容器時,子項會相對於的收縮相對比例(flex-shrink
:1)
適用場景
適用於子項總長度小於總容器的場景,例如按鈕、標題、小圖示等小部件的排版佈局
flex: 0 和 flex: none 的區別
flex: 0
等同於設定 flex: 0 1 0%
,flex:none
等同於 flex: 0 0 auto
flex: 0
,因為是一個值且為數值,所以它表示 flex-grow
,後續我發現只用設定了flex: 數字
,那麼 flex-basis
就自動成了 0%,所以,設定flex:0
的元素的最終尺寸表示為最小內容寬度;
注意:
flex: 1 === flex: 1 1 0%
flex: 0 === flex: 0 1 0%
flex 設定為數字後,雖然
flex-basis
為最小寬度,但是前者的flex-grow
有值,可以把子項擴充滿容器,後者為 0,不擴充套件
flex: none
,既不是數值也不是長度值,none
關鍵字。flex: 0 0 auto
表示元素尺寸不會收縮也不會擴充套件,再加上 flex-basis: auto
表示固定尺寸由內容決定,由於元素不具有彈性,因為,元素內的元素不會換行,最終尺寸通常表現為最大內容寬度
適用使用 flex: 0 的場景
無論文字的內容給如何設定,左側內容的寬度都是影像的寬度
適合使用 flex: none 的場景
當 flex 子項的寬度就是內容的寬度,且內容永遠不會換行,則適合使用 flex:none
,例如如下的場景,圖片和按鈕固定長度,內容彈性
flex: 1 和 flex: auto 的區別和適用場景
flex:1
等同於設定 flex: 1 1 0%
,flex: auto
等同於 flex: 1 1 auto
可以看出兩者的 flex-grow
和 flex-shrink
都是一樣的,意味著它們都可以彈性擴充套件以及彈性收縮,區別在於 flex: 1
中 flex-basis
為 0,即寬度為 0。flex:auto
中的 flex-basis
為 auto,即寬度為自身寬度
表現的樣子為:
這裡需要解釋一下,因為我最開始也不理解,其公式為:
每個子項的寬度 = (總寬度 - flex-basis
的寬度)/ 3(以這個例子為例)
因為 flex:1
的 flex-basis
的寬度為 0 ,所以最後它的總寬度擴張或者收縮時每個子項都能等分
適用於 flex: 1 的場景
當希望元素充分利用剩餘空間,同時不會侵佔其他元素應用的寬度的適用,適合適用 flex:1
,例如所有的等分列表
之前適用 flex: none
的例子,同樣設定文字部分flex: 1
也能實現類似的效果
適用於 flex: auto 的場景
當希望元素充分利用剩餘空間,但是各自的尺寸按照各自內容進行分配的時候,適用於 flex: auto
例如導航數量不固定,每個導航文字數量頁不固定的導航效果就適合適用 flex: auto
回過頭來看之前說的面試題
flex: 0 1 auto
怎麼理解?flex: 1
具體代表什麼,有什麼應用場景flex: 0
、flex: 1
、flex: none
、flex: auto
,表示什麼意思,並應用在什麼場景下使用?
第一個問題回答
flex 的預設值為 0 1 auto,表示容器剩餘空間有多餘的時候不擴充套件,不足的時候收縮,子項的寬度根據自身的寬度來展示
第二個問題回答
腦子思考 flex 的值如果是一個值且為數字,說明是 flex-grow:1
,當它為數字時,flex-basis
會自動變成 0,所以它具體表示為 flex:1 1 0%
,表示容器剩餘空間有多餘的時候擴充套件,不足的時候收縮,子項的寬度為 0。它一般適用於充分利用剩餘空間,又不侵佔其他元素的寬度,例如等分佈局
第三個問題回答
flex:0
,表示 flex: 0 1 0%
,表示容器剩餘空間有多餘的時候不擴充套件,不足的時候收縮,子項的寬度為 0,適用設定在替換元素的父元素上
flex:1
,看第二個回答
flex: none
,表示 flex: 0 0 auto
,表示容器剩餘空間有多餘的時候不擴充套件,不足的時候也不收縮,子項的寬度為自身寬度,適用於不換行的內容或者較少的小控制元件元素上
flex: auto
,表示 flex: 1 1 auto
,表示容器剩餘空間有多餘的時候擴充套件,不足的時候收縮,子項的寬度為自身寬度,適用於基於內容動態適配的佈局(例如導航數量文字長度不固定)
flex:initial
,表示 flex: 0 1 auto
,表示容器剩餘空間有多餘的時候不擴充套件,不足的時候收縮,子項的寬度為自身寬度,適用於小控制元件元素的分佈佈局,或者某一項內容動態變化的佈局
參考資料
本文參與了 SegmentFault 思否徵文「如何“反殺”面試官?」,歡迎正在閱讀的你也加入。