關於 flex 面試題總結

山頭人漢波發表於2022-04-07

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: 0flex: 1flex: noneflex: 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-shrinkflex-basis 的值分別是 1 和 0%。注意,這裡的 flex-basis 的值是 0%,而不是預設值 auto

    • 只要改變 flex: 數字flex-basis 的值就為 0
  • 一個有效的寬度(width)值,表現形式為長度值,例如 flex: 100px,表示flex-basis: 100px,基礎尺寸為 100px。此時,flex-growflex-shrink 的值都是 1,注意,這裡的 flex-grow 的值是 1,而不是預設值 0
  • 關鍵字 noneautoinitial

雙值語法:

如果 flex 的屬性值有兩個值,則第 1 個值一定是 flex-grow,第 2 個根據值的型別不同表示不同的 CSS 屬性,具體規則如下:

  • 數值:例如flex: 1 2,則這個 2 表示 flex-shrink,此時 flex-basis 的值為 0%,而非預設值 auto
  • 長度值,例如flex: 1 100px,則這個 100pxflex-basis,此時 flex-shrink 預設值為 0

三值語法:

如果 flex 的屬性值有 3 個值,則長度值表示 flex-basis,其餘 2 個數值分別表示flex-growflex-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: initialflex: 0 1 auto初始值,常用
flex: 0flex: 0 1 0%適用場景少
flex: noneflex: 0 0 auto推薦
flex: 1flex: 1 1 0%推薦
flex: autoflex: 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:0的應用場景

無論文字的內容給如何設定,左側內容的寬度都是影像的寬度

適合使用 flex: none 的場景

當 flex 子項的寬度就是內容的寬度,且內容永遠不會換行,則適合使用 flex:none,例如如下的場景,圖片和按鈕固定長度,內容彈性

flex:none適用場景

flex: 1 和 flex: auto 的區別和適用場景

flex:1 等同於設定 flex: 1 1 0%flex: auto 等同於 flex: 1 1 auto

可以看出兩者的 flex-growflex-shrink 都是一樣的,意味著它們都可以彈性擴充套件以及彈性收縮,區別在於 flex: 1flex-basis 為 0,即寬度為 0。flex:auto 中的 flex-basis為 auto,即寬度為自身寬度

表現的樣子為:

flex:1

這裡需要解釋一下,因為我最開始也不理解,其公式為:

每個子項的寬度 = (總寬度 - flex-basis 的寬度)/ 3(以這個例子為例)

因為 flex:1flex-basis 的寬度為 0 ,所以最後它的總寬度擴張或者收縮時每個子項都能等分

適用於 flex: 1 的場景

當希望元素充分利用剩餘空間,同時不會侵佔其他元素應用的寬度的適用,適合適用 flex:1,例如所有的等分列表

之前適用 flex: none 的例子,同樣設定文字部分flex: 1 也能實現類似的效果

flex:1

適用於 flex: auto 的場景

當希望元素充分利用剩餘空間,但是各自的尺寸按照各自內容進行分配的時候,適用於 flex: auto

例如導航數量不固定,每個導航文字數量頁不固定的導航效果就適合適用 flex: auto

flex-auto

回過頭來看之前說的面試題

  1. flex: 0 1 auto 怎麼理解?
  2. flex: 1具體代表什麼,有什麼應用場景
  3. flex: 0flex: 1flex: noneflex: 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 思否徵文「如何“反殺”面試官?」,歡迎正在閱讀的你也加入。

相關文章