通過動圖形象地為你介紹 flexbox 是如何工作的(二)

作者:Scott Domes

編譯:胡子大哈

翻譯原文:http://huziketang.com/blog/posts/detail?postId=58acfdc6204d50674934c3aa

英文原文:Even more about how Flexbox works?—?explained in big, colorful, animated gifs

** 轉載請注明出處,保留原文鏈接以及作者信息**


上一篇文章中,我們介紹了 flexbox 的幾個屬性: flex-direction,justify-content,align-itemsalign-self。

這些屬性在創建基本布局上是特別有用的。而一旦你開始用 flexbox 創建網站的時候,你需要對其進行深挖以最大化地發揮它的價值。

現在我們來深入探討一下 flexbox 的縮放,并且學習如何利用它來構建適應性強而且漂亮的布局。

屬性1:flex-basis

上一篇文章中,主要介紹了應用在容器上的屬性。這次我們專門介紹如何在子元素進行縮放。

首先要介紹的第一個屬性在我看來可能是 flexbox 教程里面解釋的最少的屬性之一。

但是不要擔心,其實它很簡單。

flex-basis 控制的是一個元素的默認尺寸,但是它可以被flexbox 的其他屬性所影響(稍后會詳細介紹)。

下面這個 GIF 表示的是它和 width 屬性是可以互換的。

然而,flex-basiswidth 不同的地方是,它是和 flex 坐標軸保持一致的。

flex-basis 是在主軸方向上影響元素大小的。

我們來看一下,當保持 flex-basis 不變的情況下,改變主軸方向,會發生什么。

這里要注意,原來設置的是 height 屬性,現在必須要手動地設置 width 屬性。flex-basis 根據 flex-direction 的不同會影響到 width 或者 height。

屬性2:flex grow

接下來會有點復雜。

首先,把所有的方塊 width 都設置為120px:

現在來介紹一個屬性 flex-grow,它的默認值是 0。意味著這些方塊不允許自動填充剩下的空間。

這又是什么意思呢?讓我們來看看,如果把各個方塊的 flex-grow 設置成 1 會發生什么:

所有方塊一起充滿了整個容器的寬度,并且它們之間的間隙也都是相同的,說明 flex-grow 覆蓋了 width。

關于 flex-grow 讓人疑惑的地方在于它的值具體表達什么意思呢?flex-grow: 1 意味著什么呢?

為了解釋這個問題,我們把每個方塊的 flex-grow 值設置成 999,看一下效果:

可以看到,并沒有變化。

這是因為:flex-grow 并不是一個絕對值,而是一個相對值。

對于每個方塊來說,重要的不是 flex-grow 的值是多大,而是它的這個值和其他方塊的這個值相比較,相對大小是怎么樣的。

如果設置每個方塊為 flex-grow: 1,然后逐漸改變第三個方塊的 flex-grow,可以看到下圖的改變:

為了完全理解這個知識點,我們來快速簡單地來計算一下。

每個方塊 flex-grow 的起始值都是 1。把所有方塊的該值加起來,總和是 6。因此容器的總寬度被分成了 6 份。每個方塊就被擴展到容器所有可用空間的 1/6。

然后設置第三個方塊的 flex-grow 值為 2。那么容器的寬度被分成 7 等份,因為所有 flex-grow 屬性是:1 + 1 + 2 + 1 + 1 + 1。

第三個方塊占了整個容器空間的 2/7,其他的占了 1/7。

同理,當設置第三個方塊的 flex-grow: 3 的時候,整個容器寬度被分成了 8 份(1 + 1 + 3 + 1 + 1 + 1),第三個方塊占了 3/8,其他的占了 1/8。

以此類推。

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

重點在于,每個方塊的 flex-grow 和其他方塊的是成比例的

最后要注意的是,和 flex-basis 一樣,flex-grow 也是應用在主軸上的。除非把 flex-direction 設置為 column,否則 flex-grow 只會影響方塊的寬度。

屬性3:flex shrink

flex-shrink 剛好和 flex-grow 相反,它是決定方塊收縮多少的。

它只應用于元素必須要縮小以適應容器的情況,即容器太小了。

它的主要用法是指定哪個元素你想要縮小,哪個不想縮小。默認情況是每個方塊都 flex-shrink: 1,這表示每個方塊都會隨著容器的縮小而縮小。

我們來實戰中體會一下,在下面的 GIF 圖中,每個方塊的 flex-grow 都是 1,所以它們填滿了整個容器。每個方塊的 flex-shrink 也都是 1,所以它們也會像下面圖中這樣收縮。

接下來我們來設置第三個方塊的 flex-shrink 值為 0。不允許它收縮,所以它會隨著容器拉伸而拉伸,但是當容器收縮的時候,卻不允許比它的 120px 的width 還小。

flex-shrink 的默認值是 1,說明除非你特定地去設定這個值,否則元素都是默認收縮的。

同樣,flex-shrink 是和比例相關的。如果設置一個方塊的 flex-shrink 為 6,而其他的是 2,那么這個方塊隨著容器空間的壓縮,將以 3 倍于其他方塊的速度縮小。

這里尤其注意:是收縮的速度是 3 倍,而不是說它的寬度會縮小到原來的 1/3。

接下來準備更深入探討元素是如何收縮和拉伸的。不過在這之前,還需要介紹最后一個屬性,把這些東西都串起來。

屬性4:flex

flexgrow,shrinkbasis 的簡化形式——把它們所有都放到了一起。

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

我們把上一個例子簡化成只有兩個方塊,下面是它們的屬性:

.square#one {
  flex: 2 1 300px;
}
.square#two {
  flex: 1 2 300px;
}

兩個方塊都有著相同的 flex-basis。也就是說如果有足夠的空間(容器的空間等于 600px 加上 margin 和 padding),它們的寬度將都會是 300px。

但是隨著容器的拉伸,方塊 1(有更大的 flex-grow 值)將會以兩倍的速度增長。隨著容器的收縮,方塊 2 (有更大的 flex-shrink 值)將會以兩倍的速度收縮。

都放到一起展示,如下圖:

元素是怎樣收縮和拉伸的呢

有些人可能會疑惑地發現:當方塊 1 拉伸時,并沒有拉伸到方塊 2 的兩倍大小。同樣,當方塊 2 縮小時,也并沒有縮小到方塊 1 的一半,盡管 flex-shrink 的比值是 2:1。

實際上這兩個屬性的意思,并不是說它們的大小是 2:1 或者 1:2,而是說它們的收縮率或拉伸率。

來點簡單的計算

容器的初始大小是 640px。在除去容器要預留的 20px 的 padding 后,剩下的空間足夠讓兩個方塊滿足 flex-basis 等于 300px。

當把容器設置為 430px 時,空間減小了 210px。方塊 1,設置了 flex-shrink 是 1,減小了 70px。而方塊 2,設置了 flex-shrink 是 2,減小了 140px。

當容器縮小到了 340px,容器空間減小了 300px。這時方塊 1 減小 100px,而方塊 2 減小 200px。

整體減小空間的分配方式,是按照各自設置的 flex-shrink 比例分配的(2:1)。

對于 flex-grow 也一樣。當容器拉伸到 940px 時,整體增加了 300px,方塊 1 增加 200px,而方塊 2 增加 100px。

當涉及到 flex 屬性時,其實它們說的都是比例

從上圖中,可以看到寬度是如何根據設置的比例變化的,其中的 delta (?) 表示和原始 flex-basis 相比的變化量。

結論

最后總結一下:flex-basis 指的是一個元素在發生縮放之前,沿著主軸方向的大小。flex-grow 指的是在元素拉伸時,和兄弟元素相比的拉伸比例。flex-shrink 指的是在元素收縮時,和兄弟元素相比的收縮比例。

我們還有幾個 flexbox 屬性要講,請留意隨后幾周的文章。


我最近正在寫一本《React.js 小書》,對 React.js 感興趣的童鞋,歡迎指點。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容

  • 前言 FlexBox是css3的一種新的布局方式,天生為解決布局問題而存在的它,比起傳統的布局方式,我們使用Fle...
    zevei閱讀 1,429評論 23 3
  • H5移動端知識點總結 閱讀目錄 移動開發基本知識點 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇閱讀 4,599評論 0 26
  • 移動開發基本知識點 一.使用rem作為單位 html { font-size: 100px; } @media(m...
    橫沖直撞666閱讀 3,504評論 0 6
  • title: flex布局date: 2017-07-07 14:13:33tags: css筆記 flexbox...
    Gary23閱讀 1,546評論 0 0
  • 在以前頁面布局多依賴于table,但table標簽太多,于是有了absolute布局,float布局等,但它們小問...
    張歆琳閱讀 4,131評論 3 55