天天看點

聊聊Flexbox布局中的flex的演算法

到目前為止,Flexbox布局應該是目前最流行的布局方式之一了。而Flexbox布局的最大特性就是讓Flex項目可伸縮,也就是讓Flex項目的寬度和高度可以自動填充Flex容器剩餘的空間或者縮小Flex項目适配Flex容器不足的寬度。而這一切都是依賴于Flexbox屬性中的

flex

屬性來完成。一個Flex容器會等比的按照各Flex項目的擴充比率配置設定Flex容器剩餘空間,也會按照收縮比率來縮小各Flex項目,以免Flex項目溢出Flex容器。但其中Flex項目又是如何計算呢?他和擴充比率或收縮比率之間又存在什麼關系呢?在這篇文章中我們将一起來探來。

在Flexbox布局中,容器中顯示式使用

display

設定為

flex

inline-flex

,那麼該容器就是Flex容器,而該容器的所有子元素就是Flex項目。

簡介

在這篇文章中,我們将要聊的是有關于

flex

屬性的事情,特别是如何使用該屬性來計算Flex項目?在開始之前,先來簡單的了解一下

flex

屬性。

在Flexbox中,

flex

屬性是

flex-grow

(擴充比率)、

flex-shrink

(收縮比率)和

flex-basis

(伸縮基準)三個屬性的簡稱。這三個屬性可以控制一個Flex項目(也有人稱為Flex元素),主要表現在以下幾個方面:

  • flex-grow

    :Flex項目的擴充比率,讓Flex項目得到(伸張)多少Flex容器多餘的空間(Positive free space)
  • flex-shrink

    :Flex項目收縮比率,讓Flex項目減去Flex容器不足的空間(Negative free space)
  • flex-basis

    :Flex項目未擴充或收縮之前,它的大小是多少

在Flexbox布局中,隻有充分了解了這三個屬性才能徹底的掌握Flex項目是如何擴充和收縮的,也才能更徹底的掌握Flexbox布局。是以掌握這三個屬性,以及他們之間的計算關系才是掌握Flexbox布局的關鍵所在。

相關概念

在具體介紹

flex

相關的技術之前,先對幾個概念進行描述,因為了解了這幾個概念更有易于大家對後面知識的了解。

主軸長度和主軸長度屬性

Flex項目在主軸方向的寬度或高度就是Flex項目的主軸長度,Flex項目的主軸長度屬性是

width

height

屬性,具體是哪一個屬性,将會由主軸方向決定。

聊聊Flexbox布局中的flex的演算法

剩餘空間和不足空間

在Flexbox布局中,Flex容器中包含一個或多個Flex項目(該容器的子元素或子節點)。Flex容器和Flex項目都有其自身的尺寸大小,那麼就會有:Flex項目尺寸大小之和大于或小于Flex容器 情景:

  • 當所有Flex項目尺寸大小之和小于Flex容器時,Flex容器就會有多餘的空間沒有被填充,那麼這個空間就被稱為Flex容器的剩餘空間(Positive Free Space)
  • 當所有Flex項目尺寸大小之和大于Flex容器時,Flex容器就沒有足夠的空間容納所有Flex項目,那麼多出來的這個空間就被稱為負空間(Negative Free Space)

舉個例子向大家闡述這兩個情形:“假設我們有一個容器(Flex容器),顯式的給其設定了

width

800px

padding

10px

,并且

box-sizing

border-box

”。根據CSS的盒模型原理,我們可以知道Flex容器的内寬度(Content盒子的寬度)為

800px - 10px * 2 = 780px

聊聊Flexbox布局中的flex的演算法

假設Flex容器中包含了四個Flex項目,而且每個Flex項目的

width

都為

100px

,那麼所有Flex項目的寬度總和則是

100px * 4 = 400px

(Flex項目沒有設定其他任何有關于盒模型的尺寸),那麼Flex容器将會有剩餘的空間出來,即

780px - 400px = 380px

。這個

380px

就是我們所說的Flex容器的剩餘空間:

聊聊Flexbox布局中的flex的演算法

假設把Flex項目的

width

100px

調到

300px

,那麼所有Flex項目的寬度總和就變成了

300px * 4 = 1200px

。這個時候Flex項目就溢出了Flex容器,這個溢出的寬度,即

1200px - 780px = 420px

420px

就是我們所說的Flex容器的不足空間:

聊聊Flexbox布局中的flex的演算法
上面示範的是主軸在

x

軸方向,如果主軸變成

y

軸的方向,同樣存在上述兩種情形,隻不過把

width

變成了

height

。接下來的内容中,如果沒有特殊說明,那麼所看到的示例都僅示範主軸在

x

軸的方向,即

flex-direction

row

min-content 和 max-content

min-content

max-content

是CSS中的一個新概念,隸屬于

CSS Intrinsic and Extrinsic Sizing Specification

子產品。簡單的可以這麼了解。

CSS可以給任何一個元素顯式的通過

width

屬性指定元素内容區域的寬度,内容區域在元素

padding

border

margin

裡面。該屬性也是CSS盒模型衆多屬性之一。

記住,CSS的

box-sizing

可以決定

width

的計算方式。

如果我們顯式設定

width

為關鍵詞

auto

時,元素的

width

将會根據元素自身的内容來決定寬度。而其中的

min-content

max-content

也會根據元素的内容來決定寬度,隻不過和

auto

有較大的差異

  • min-content

    : 元素固有的最小寬度
  • max-content

    : 元素固有的首選寬度

比如下面這個示例:

聊聊Flexbox布局中的flex的演算法

如果内容是英文的話,

min-content

的寬度将取決于内容中最長的單詞寬度,中文就有點怪異(其中之因目前并未深究),而

max-content

則會計算内容排整行的寬度,有點類似于加上了

white-space:nowrap

一樣。

上例僅展示了

min-content

max-content

最基本的渲染效果(Chrome浏覽器渲染行為)。這裡不做深入的探讨論,畢竟不是本文的重點,如果感興趣,歡迎關注後續的相關更新,或者先閱讀@張鑫旭 老師寫的一篇文章《 了解CSS3

max/min-content

fit-content

width

回到我們自己的主題上來。

前面在介紹Flex剩餘空間和不足空間的時候,我們可以得知,出現這兩種現象取決于Flex容器和Flex項目的尺寸大小。而

flex

屬性可以根據Flex容器的剩餘空間(或不足空間)對Flex項目進行擴充(或收縮)。那麼為了計算出有多少Flex容器的剩餘空間能用于Flex項目上,用戶端(浏覽器)就必須知道Flex項目的尺寸大小。要是沒有顯式的設定元素的

width

屬性,那麼問題就來了,浏覽器它是如何解決沒有應用于絕對機關的寬度(或高度)的Flex項目,即如何計算?

這裡所說的

min-content

max-content

兩個屬性值對于我們深入的探讨

flex

屬性中的

flex-grow

flex-grow

屬性有一定的影響。是以提前向大家簡單的闡述一正是這兩個屬性值在浏覽器中的渲染行為。

簡單的總結一下:

min-content

的大小,從本質上講,是由字元串中最長的單詞決定了大小;

max-content

則和

min-content

想反. 它會變得盡可能大, 沒有自動換行的機會。如果Flex容器太窄, 它就會溢出其自身的盒子!
聊聊Flexbox布局中的flex的演算法

Flex項目的計算

在Flexbox布局當中,其中

flex-grow

flex-shrink

flex-basis

都将會影響Flex項目的計算。接下來我們通過一些簡單的示例來闡述這方面的知識。

flex-basis

flex-basis

屬性在任何空間配置設定發生之前初始化Flex項目的尺寸。其預設值為

auto

。如果

flex-basis

的值設定為

auto

,浏覽器将先檢查Flex項目的主尺寸是否設定了絕對值再計算出Flex項目的初始值。比如說,你給Flex項目設定的

width

200px

,那麼

200px

就是Flex項目的

flex-basis

值。

如果你的Flex項目可以自動調整大小,則

auto

會解析為其内容的大小,這個時候,

min-content

max-content

變會起作用。此時将會把Flex項目的

max-content

作為

flex-basise

的值。比如,下面這樣的一個簡單示例:

flex-grow

flex-shrink

的值都為

,第一個Flex項目的

width

150px

,相當于

flex-basis

的值為

150px

,而另外兩個Flex項目在沒有設定寬度的情況之下,其寬度由内容的寬度來設定。

聊聊Flexbox布局中的flex的演算法

如果

flex-basis

的值設定為關鍵詞

content

,會導緻Flex項目根據其内容大小來設定Flex項目,叧怕是Flex項目顯式的設定了

width

的值。到目前為止,

content

還未得到浏覽器很好的支援。

flex-basis

除了可以設定

auto

content

fill

max-content

min-content

fit-content

關鍵詞之外,還可以設定

<length>

值。如果

<length>

值是一個百分比值,那麼Flex項目的大小将會根據Flex容器的

width

進行計算。比如下面這個示例:

聊聊Flexbox布局中的flex的演算法

Flex容器顯式設定了

width

(和

box-sizing

取值有關系,上圖為

border-box

的示例結果),那麼

flex-basis

會根據Flex容器的

width

計算出來,如果Flex容器未顯示設定

width

值,則計算出來的結果将是未定義的(會自動根據Flex容器的寬度進行計算)。

在Flexbox布局中,如果你想完全忽略Flex項目的尺寸,則可以将

flex-basis

。這樣的設定,基本上是告訴了浏覽器,Flex容器所有空間都可以按照相關的比例進行配置設定。

來看一個簡單的示例,Flex項目未顯式設定

width

情況之下,

flex-basis

不同取值的渲染效果。

到寫這篇文章為止,使用Firefox浏覽器檢視效果更佳。
聊聊Flexbox布局中的flex的演算法

當Flex項目顯式的設定了

min-width

max-width

的值時,就算Flex項目顯式的設定了

flex-basis

的值,也會按

min-width

max-width

設定Flex項目寬度。當計算的值大于

max-width

時,則按

max-width

設定Flex項目寬度;當計算的值小于

min-width

min-width

設定Flex項目寬度:

聊聊Flexbox布局中的flex的演算法

有關于

flex-basis

屬性相關的運用簡單的小結一下:

  • flex-basis

    預設值為

    auto

  • 如果Flex項目顯式的設定了

    width

    值,同時

    flex-basis

    auto

    時,則Flex項目的寬度為按

    width

    來計算,如果未顯式設定

    width

    ,則按Flex項目的内容寬度來計算
  • width

    值,同時顯式設定了

    flex-basis

    的具體值,則Flex項目會忽略

    width

    值,會按

    flex-basis

    來計算Flex項目
  • 當Flex容器剩餘空間不足時,Flex項目的實際寬度并不會按

    flex-basis

    來計算,會根據

    flex-grow

    flex-shrink

    設定的值給Flex項目配置設定相應的空間
  • 對于Flexbox布局中,不建議顯式的設定Flex項目的

    width

    值,而是通過

    flex-basis

    來控制Flex項目的寬度,這樣更具彈性
  • min-width

    max-width

    值時,當

    flex-basis

    計算出來的值小于

    min-width

    則按

    min-width

    值設定Flex項目寬度,反之,計算出來的值大于

    max-width

    值時,則按

    max-width

    的值設定Flex項目寬度

flex-grow

前面提到過,

flex-grow

是一個擴充因子(擴充比例)。其意思是,當Flex容器有一定的剩餘空間時,

flex-grow

可以讓Flex項目配置設定Flex容器剩餘的空間,每個Flex項目将根據

flex-grow

因子擴充,進而讓Flex項目布滿整個Flex容器(有效利用Flex容器的剩餘空間)。

flex-grow

的預設值是

,其接受的值是一個數值,也可以是一個小數值,但不支援負值。一旦

flex-grow

的值是一個大于

的值時,Flex項目就會占用Flex容器的剩餘空間。在使用

flex-grow

時可以按下面的方式使用:

  • 所有Flex項目設定相同的

    flex-grow

  • 每個Flex項目設定不同的

    flex-grow

不同的設定得到的效果将會不一樣,但

flex-grow

的值始終總量為

1

,即Flex項目占有的量之和(分子)和分母相同。我們來具體看看

flex-grow

對Flex項目的影響。

當所有的Flex項目具有一個相同的

flex-grow

值時,那麼Flex項目将會平均配置設定Flex容器剩餘的空間。在這種情況之下将

flex-grow

1

。比如下面這個示例,Flex容器(

width: 800px

padding: 10px

)中有四個子元素(Flex項目),顯式的設定了

flex-basis

150px

,根據前面介紹的内容,我們可以知道每個Flex項目的寬度是

150px

,這樣一來,所有Flex項目寬度總和為

150px * 4 = 600px

。容器的剩餘空間為

780px - 600px = 180px

。當顯式的給所有Flex項目設定了

flex-grow

1

(具有相同的值)。這樣一來,其告訴浏覽器,把Flex容器剩餘的寬度(

180px

)平均分成了四份,即:

180px / 4 = 45px

。而

flex-grow

的特性就是按比例把Flex容器剩餘空間配置設定給Flex項目(當然要設定了該值的Flex項目),就該例而言,就是給每個Flex項目添加了

45px

,也就是說,此時Flex項目的寬度從

150px

擴充到了

195px

150px + 45px = 195px

)。如下圖所示:

聊聊Flexbox布局中的flex的演算法
特别聲明,如果Flex項目均分Flex容器剩餘的空間,隻要給Flex項目設定相同的

flex-grow

值,大于

1

即可。比如把

flex-grow

10

,就上例而言,把剩餘空間分成了

40

份,每個Flex項目占

10

份。其最終的效果和設定為

1

是等效的。

上面我們看到的均分Flex容器剩餘空間,事實上我們也可以給不同的Flex項目設定不同的

flex-grow

值,這樣一來就會讓每個Flex項目根據自己所占的比例來占用Flex容器剩餘的空間。比如上面的示例,把Flex項目的

flex-grow

分别設定為

1:2:3:4

。也就是說把Flex容器的剩餘空間分成了

10

份(

1 + 2 + 3 + 4 = 10

),而每個Flex項目分别占用Flex容器剩餘空間的

1/10

2/10

3/10

4/10

。就上例而言,Flex容器剩餘空間是

180px

,按這樣的計算可以得知,每一份的長度是

180px / 10 = 18px

,如此一來,每個Flex項目的寬度則變成:

  • Flex1:

    150px + 18px * 1 = 168px

  • Flex2:

    150px + 18px * 2 = 186px

  • Flex3:

    150px + 18px * 3 = 204px

  • Flex4:

    150px + 18px * 4 = 222px

最終效果如下圖所示:

聊聊Flexbox布局中的flex的演算法

前面兩個示例向大家示範了,Flex項目均分和非均分Flex容器剩餘的空間。從示例中可以看出來,

flex-grow

的值都是大于或等于

1

的數值。事實上,

flex-grow

還可以設定小數。比如,給所有Flex項目設定

flex-grow

0.2

。由于Flex項目的

flex-grow

的值都相等,是以擴充的值也是一樣的,唯一不同的是,所有的Flex項目并沒有把Flex容器剩餘空間全部分完。就我們這個示例而言,四個Flex項目的

flex-grow

加起來的值是

0.8

,小于

1

。換句話說,四個Flex項目隻配置設定了Flex容器剩餘空度的

80%

,按上例的資料來計算,即是

180px * .8 = 144px

(隻分去了

144px

),而且每個Flex項目分得都是

36px

144px / 4 = 36px

或者

144px * 0.2 / 0.8 = 36px

)。最終效果如下圖所示:

聊聊Flexbox布局中的flex的演算法

上面的示例中,

flex-basis

都顯式的設定了值。事實上,

flex-grow

flex-basis

會互相影響的。這也令我們的Flex項目計算變得複雜化了。比如說,

flex-basis

auto

,而且沒有給Flex項目顯式的設定

width

。根據前面的内容我們可以得知,此時Flex項目的大小都取決于其内容的

max-content

大小。此時Flex容器的剩餘的空間将由浏覽器根據Flex項目的内容寬度來計算。比如接下來的這個示例,四個Flex項目都是由其内容

max-content

大小決定。同時将

flex-grow

都設定為

1

(均勻配置設定Flex容器剩餘空間)。具體的資料由下圖所示(Chrome浏覽器計算得出的值):

聊聊Flexbox布局中的flex的演算法
特别注意,不同浏覽器對小數位的計算略有差異,上圖是在Chrome浏覽器下得出的值。是以最終加起來的值略大于Flex容器的寬度

708px

針對這樣的使用場景,如果你想讓所有Flex項目具有相同的尺寸,那麼可以顯式的設定Flex項目的

flex-basis

值為

flex: 1 1 0

)。從

flex-basis

一節中可以得知,當

flex-basis

時,表示所有空間都可以用來配置設定,而且

flex-grow

具有相同的值,是以Flex項目可以擷取均勻的空間。如此一來Flex項目寬度将會相同。

flex-basis

還可以由其他值為設定Flex項目的寬度,這裡不再一一示範。感興趣的同學可以自己根據

flex-basis

的取值寫測試用例。換句話說,如果你了解了前面介紹的

flex-basis

内容,就能更好的了解

flex-grow

flex-basis

相結合對Flex項目配置設定Flex容器剩餘空間的計算。也将不會再感到困惑。

flex-shrink

flex-shrink

flex-grow

類似,隻不過

flex-shrink

是用來控制Flex項目縮放因子。當所有Flex項目寬度之和大于Flex容器時,将會溢出容器(

flex-wrap

nowrap

時),

flex-shrink

就可以根據Flex項目設定的數值比例來配置設定Flex容器的不足空間,也就是按比例因子縮小自身的寬度,以免溢出Flex容器。

flex-shrink

接收一個

<number>

值,其預設值為

1

。也就是說,隻要容器寬度不足夠容納所有Flex項目時,所有Flex項目預設都會收縮。如果你不想讓Flex項目進行收縮時,可以設定其值為

,此時Flex項目始終會保持原始的

fit-content

寬度。同樣的,

flex-shrink

也不接受一個負值做為屬性值。

基于上面的示例,簡單的調整一下參數,所有Flex項目都設定了

flex: 0 0 300px

,可以看到Flex項目溢出了Flex容器:

聊聊Flexbox布局中的flex的演算法

在這個示例中,由于

flex-shrink

顯式的設定了值為

,Flex項目不會進行收縮。如果你想讓Flex項目進行收縮,那麼可以把

flex-shrink

1

聊聊Flexbox布局中的flex的演算法

從上圖的結果我們可以看出,當所有Flex項目的

flex-shrink

都設定為相同的值,比如

1

,将會均分Flex容器不足空間。比如此例,所有Flex項目的寬度總和是

1200px

flex-basis: 300px

),而Flex容器寬度是

780px

width: 800px

padding: 10px

,盒模型是

border-box

),可以算出Flex容器不足空間為

420px

1200 - 780 = 420px

),因為所有Flex項目的

flex-shrink

1

,其告訴浏覽器,将Flex容器不足空間均分成四份,那麼每份則是

105px

420 / 4 = 105px

),這個時候Flex項目就會自動縮放

105px

,其寬度就由當初的

300px

195px

300 - 105 = 195px

)。

這個示例示範的是Flex項目設定的值都是相同的值,其最終結果是将會均分Flex容器不足空間。其實

flex-shrink

也可以像

flex-grow

一樣,為不同的Flex項目設定不同的比例因子。比如

1:2:3:4

,這個時候Flex項目就不會均分了,而是按自己的比例進行收縮,比例因子越大,收縮的将越多。如下圖所示:

聊聊Flexbox布局中的flex的演算法

就上圖而言,所有Flex項目的

flex-shrink

之和為

10

1 + 2 + 3 + 4 = 10

),此時把Flex容器不足空間

420px

分成了十份,每一份

42px

420 / 10 = 42px

),每個Flex項目按照自己的收縮因子相應的去收縮對應的寬度,此時每個Flex項目的寬度就變成:

  • 300 - 42 * 1 = 258px

  • 300 - 42 * 2 = 216px

  • 300 - 42 * 3 = 174px

  • 300 - 42 * 4 = 132px

按照該原理來計算的話,當某個Flex項目的收縮因子設定較大時,就有可能會出現小于

的現象。基于上例,如果把第四個Flex項目的

flex-shrink

15

。這樣一來,四個Flex項目的收縮因子就變成:

1:2:3:15

。也就是說把Flex容器不足空間分成了

21

份,每份占據的寬度是

20px

420 / 21 = 20px

)。那麼Flex項目的寬度就會出現

的現象(

300 - 15 * 20 = 0

)。這個時候會不會出現無空間容納Flex項目的内容呢?事實上并不會這樣:

在Flexbox布局當中,會阻止Flex項目元素寬度縮小至 。此時Flex項目會以

min-content

的大小進行計算,這個大小是它們利用任何可以利用的自動斷行機會後所變成的

如果某個Flex項目按照收縮因子計算得出寬度趨近于

時,Flex項目将會按照該元素的

min-content

的大小來設定寬度,同時這個寬度将會轉嫁到其他的Flex項目,再按相應的收縮因子進行收縮。比如上例,Flex項目四,其

flex-shrink

15

,但其寬度最終是以

min-content

來計算(在該例中,Chrome浏覽器渲染的寬度大約是

22.09px

)。而這個

22.09px

最終按照

1:2:3

的比例配置設定給了Flex項目一至三(Flex1,Flex2和Flex3)。對應的Flex項目寬度就變成:

  • 300 - 20 * 1 - 22.09 / 6 * 1 = 276.334px

  • 300 - 20 * 2 - 22.09 / 6 * 2 = 252.636px

  • 300 - 20 * 3 - 22.09 / 6 * 3 = 228.955px

  • min-content

    ,在該例中大約是

    22.09px

對于該情形,計算相對而言就更為複雜一些了。但浏覽器會很聰明的幫你處理這些場景,會傾向于給你合理的結果。隻不過大家需要知道這樣的一個細節,碰到類似的場景才不會一臉蒙逼(^_^)。

flex-grow

可以設定一個小于

的值,同樣的,

flex-shrink

也可以設定一個小于

的值,比如我們給所有的Flex項目設定

flex-shrink

0.2

,你将看到的結果如下:

聊聊Flexbox布局中的flex的演算法

從結果的示例圖中我們可以看出來,當所有Flex項目的收縮因子(

flex-shrink

)總和小于

1

時,Flex容器不足空間不會完全配置設定完,依舊會溢出Flex容器。好比該例,

flex-shrink

的總和是

.8

,配置設定了Flex容器剩餘空間

420px

80%

,即

336px

(還有

84px

剩餘空間未完全配置設定完),由于每個Flex項目的收縮因子是相同的,好比前面的示例,都設定了

1

類似,把配置設定的空間

336px

均分為四份,也就是

84px

,是以每個Flex項目的寬度由當初的

300px

216px

300 - 84 = 216px

)。這個其實和

flex-grow

flex-shrink

隻是收縮而以。

Flex項目計算公式

Flex項目伸縮計算是一個較為複雜的過程,但它們之間還是有據可查。

@Chris @Otree

對該方面就有

深入的研究

。他們給Flex項目的計算總結出了一套計算公式,具體公式如下:

聊聊Flexbox布局中的flex的演算法
@Chris還依據這套公式寫了一個JavaScript的案例

,來模拟Flex項目計算。

flex常見的值

大部分情形之下,我們都是使用

flex

屬性來設定Flex項目的伸縮的值。其常見值的效果有:

  • flex: 0 auto

    flex:initial

    ,這兩個值與

    flex: 0 1 auto

    相同,也是初始值。會根據

    width

    屬性決定Flex項目的尺寸。當Flex容器有剩餘空間時,Flex項目無法擴充;當Flex容器有不足空間時,Flex項目收縮到其最小值

    min-content

  • flex: auto

    flex: 1 1 auto

    相同。Flex項目會根據

    width

    來決定大小,但是完全可以擴充Flex容器剩餘的空間。如果所有Flex項目均為

    flex: auto

    flex:initial

    flex: none

    ,則Flex項目尺寸決定後,Flex容器剩餘空間會被平均分給是

    flex:a uto

    的Flex項目。
  • flex: none

    flex: 0 0 auto

    相同。Flex項目根據

    width

    決定大小,但是完全不可伸縮,其效果和

    initial

    類似,這種情況下,即使在Flex容器空間不夠而溢出的情況之下,Flex項目也不會收縮。
  • flex: <positive-number>

    (正數)與

    flex: 1 0px

    相同。該值使Flex項目可伸縮,并将

    flex-basis

    值設定為 ,導緻Flex項目會根據設定的比例因子來計算Flex容器的剩餘空間。如果所有Flex項目都使用該模式,則它們的尺寸會正比于指定的伸縮比。
預設狀态下,伸縮項目不會收縮至比其最小内容尺寸(最長的英文詞或是固定尺寸元素的長度)更小。可以靠設定

min-width

屬性來改變這個預設狀态。

如何掌握Flex項目的大小

通過前面的内容介紹,應該可以了解到Flex項目的大小計算是非常的複雜。如果要真正的了解Flex項目是如何工作的話,最為關鍵的是了解有多少東西參與影響Flex項目。我們可以按下面這樣的方式來進行思考。

怎麼設定Flex項目的基本大小

在CSS中設定一個元素的基本大小可以通過

width

來設定,或者通過

min-width

max-width

來設定元素的最小或最大寬度,在未來我們還可以通過

content

min-content

max-content

fit-content

等關鍵詞來設定元素的大小。對于Flex項目,我們還可以通過

flex-basis

設定Flex項目大小。對于如何設定Flex項目的基本大小,我們可以圍繞以下幾點來進行思考:

  • flex-basis

    的值是

    auto

    ?Flex項目顯式的設定了寬度嗎?如果設定了,Flex項目的大小将會基于設定的寬度
  • flex-basis

    auto

    還是

    content

    ?如果是

    auto

    ,Flex項目的大小為原始大小
  • flex-basis

    的長度機關嗎?如果是這樣那這就是Flex項目的大小
  • flex-basis

    呢? 如果是這樣,則Flex項目的大小不在Flex容器空間配置設定計算的考慮之内

更為具體的可以參閱

flex-basis

相關的介紹。

我們有可用空間嗎?

如果Flex容器沒有剩餘空間,Flex項目就不會擴充;如果Flex容器沒有不足空間,Flex項目就不會收縮:

  • 所有的Flex項目的寬度總和是否小于Flex容器的總寬度? 如果是這樣,那麼Flex容器有剩餘空間,

    flex-grow

    會發揮作用, 具體如何發揮作用,可以參閱

    flex-grow

    相關的介紹
  • 所有的Flex項目的寬度總和是否大于Flex容器的總寬度? 如果是這樣,那麼Flex容器有不足空間,

    flex-shrink

    會發揮作用,具體如何發揮作用,可以參閱

    flex-shrink

配置設定空間的其他方式

如果我們不想把Flex容器的剩餘空間擴充到Flex項目中,我們可以使用Flexbox中其他屬性,比如

justify-content

屬性來配置設定剩餘空間。當然也可以給Flex項目設定

margin

值為處理Flex容器剩餘空間。不過這一部分沒有在這裡闡述,如果感興趣的話,不仿閱讀一下Flexbox相關的介紹。

總結

聊聊Flexbox布局中的flex的演算法

很久以為,一直以為Flexbox布局中,Flex項目都會根據Flex容器自動計算。而事實上呢?正如文章中介紹的一樣,Flex項目的計算是相當的複雜。設定Flex項目大小的值以及

flex-basis

flex-grow

flex-shrink

的設定都會對其有較大的影響,而且它們的組合場景也是非常的多,并且不同的場景會造成不一樣的結果。

當然,文章中所介紹的内容或許沒有覆寫到所有的場景,但這些基本的示範或許能幫助大家更好的了解Flex項目是如何計算的。最後希望該文對大家有所幫助,如果你有更深的了解歡迎在下面的評論中與我一起分享。如果文章中有不對之處,還望各路大嬸拍正。