一文詳解三個 flex 屬性對元素的影響

2022-08-30 22:02:46

如何快速入門VUE3.0:進入學習

在開發的時候經常用 flex 這個屬性作用於彈性盒子的子元素,例如:flex:1或者flex: 1 1 auto,那麼這個屬性到底控制了元素怎麼的行為呢?flex:1又究竟是什麼含義呢?讓這篇文章帶你徹底瞭解 flex 屬性吧!【推薦學習:】

首先我們需要了解,flex 是三個屬性 flex-growflex-shrinkflex-basis的簡寫,可以使用一個、兩個、或者三個值指定 flex 屬性。具體語法可以參考MDN-flex

接下來我們逐一拆解這三個屬性對元素的影響

flex-basis

flex-basis 定義了空間分配發生之前初始化 flex 子元素的尺寸,屬性預設值 auto; flex 子元素未伸張和收縮之前,它的大小是多少。

如果 flex-basis 設定為 auto , 瀏覽器會先檢查 flex 子元素的主尺寸是否設定了 flex 子元素的初始值。

比如說你已經給你的 flex 子元素設定了 150px 的寬,則 150px 就是這個 flex 子元素的 flex-basis;如果沒有設定,則 auto 會解析為其內容的大小。這個例子中,給第一個元素設定寬度150px,第二、三個元素不設定寬度。

:first-child {
  width: 150px;
}

效果如下:

1.png

如果你想 flexbox 完全忽略 flex 子元素的尺寸就設定 flex-basis 為 0。這樣就算元素一設定了寬度,它最終的寬度也是內容寬度。

2.png

正負自由空間

在介紹剩下兩個屬性前先看兩個概念 positive free space 正向自由空間和 negative free space反向自由空間:

  • 正向自由空間

    比如說,現在有 500px 寬的 flex 容器,flex-direction 屬性值為 row, 三個 100px 寬的 flex 子元素, 那麼沒有被填充的 200px 的 就是正向自由空間(positive free space)。

3.png

  • 反向自由空間

    當子元素的寬度總和大於容器寬度時,溢位的尺寸100px就是反向自由空間。

4.png

那麼用什麼屬性分配正負自由空間呢?

flex-grow

  • flex-grow 預設值 0,若被賦值為一個正整數, flex 元素會以 flex-basis 為基礎,沿主軸方向增長尺寸,並佔據可用空間。flex-grow 按比例分配增長空間。

初始狀態:我們給三個元素都設定寬度,並且總和不大於主軸寬度

.flex-grow-father {
  width: 500px;
  div:nth-child(1) {
    width: 50px;
  }
  div:nth-child(2) {
    width: 100px;
  }
  div:nth-child(3) {
    width: 150px;
  }
}

5.png

增加的寬度計算方法:假設元素的 flex-grow 值為 x,正向自由空間寬度為l,則每個元素增加的寬度=xx的總和l\frac{x}{x的總和}*l,元素最終寬度 = 元素初始寬度+增加的寬度元素初始寬度 + 增加的寬度

  • 相同比例增長:當給每個子元素的都設定相同的 flex-grow 值,每個元素就會增長相同的寬度
.with-same-flex-grow {
  * {
    flex-grow: 1;
  }
}

效果如下:

6.png

本例中第一個元素寬度的計算 11+1+1200+50=116.67px\frac{1}{1+1+1}*200 + 50 = 116.67px

第二個元素寬度寬度計算 11+1+1200+100=166.67px\frac{1}{1+1+1}*200 + 100 = 166.67px

第三個同理為216.67px216.67px

  • 不同比例增長:給每個子元素的都設定不同的 flex-grow 值
.with-different-flex-grow {
  div:nth-child(1) {
    flex-grow: 2;
  }
  div:nth-child(2) {
    flex-grow: 1;
  }
  div:nth-child(3) {
    flex-grow: 1;
  }
}

效果如下:

7.png

本例中第一個元素寬度的計算22+1+1200+50=150px\frac{2}{2+1+1}*200 + 50 = 150px

第二個元素寬度的計算12+1+1200+100=150px\frac{1}{2+1+1}*200 + 100 = 150px

第三個同理是200px200px

  • 如果想讓開始時尺寸不同的元素內容寬度相等(平分容器寬度),可以將 flex-basis 設定為 0(完全忽略 flex 子元素的尺寸) flex-grow 為 1(等比例分配)
.average {
  * {
    /* flex: 1 1 0; */
    flex-basis: 0;
    flex-grow: 1;
  }
}

效果如下:

8.png

flex-shrink

flex-shrink 屬性指定了 flex 元素的縮小值,預設值為 1; 它確定在分配 negative free space 時,flex 子元素相對於 flex 容器中其餘 flex 子元素收縮的程度。預設值 1。用於減少盒子空間使盒子適應容器而不溢位(為了避免 border 干擾去掉邊框)

我們給三個元素都設定寬度,並且總和大於主軸寬度;這裡我們將元素的flex-shrink值設定為 0 (元素寬度不變,不需要吸收溢位的寬度),目的是觀察一下反向自由空間。

.flex-shrink-wrapper {
  display: flex;
  div:nth-child(1) {
    width: 100px;
    background: gold;
  }
  div:nth-child(2) {
    width: 200px;
    background: tan;
  }
  div:nth-child(3) {
    width: 300px;
    background: gold;
  }
}
.zero {
  * {
    flex-shrink: 0;
  }
}

9.png

吸收的寬度計算:假設每個 flex-shrink 的值為 xnx_n,元素的初始寬度為 lnl_n,反向自由空間為LL那麼每個元素吸收的寬度為: xnlnx1l1+...+xnlnL\frac{x_n*l_n}{x_1*l_1+...+x_n*l_n}*L

  • 給子元素相同的 flex-shrink 值,這裡以預設值 1 為例
.with-same-flex-shrink {
  * {
    flex-shrink: 1;
  }
}

10.png

這時第一個元素的吸收寬度為:11001100+1200+1300100=16.67px\frac{1*100}{1*100+1*200+1*300}*100 = 16.67px,最終元素寬度為 10016.67=83.37px100-16.67=83.37px

這時第一個元素的吸收寬度為:12001100+1200+1300100=33.33px\frac{1*200}{1*100+1*200+1*300}*100 = 33.33px,最終元素寬度為 20033.33=166.67px200-33.33=166.67px

這時第一個元素的吸收寬度為:13001100+1200+1300100=50px\frac{1*300}{1*100+1*200+1*300}*100 = 50px,最終元素寬度為 30050=250px300-50=250px

  • 給子元素不同的 flex-shrink 值
.with-different-flex-shrink {
  div:nth-child(1) {
    flex-shrink: 1;
  }
  div:nth-child(2) {
    flex-shrink: 2;
  }
  div:nth-child(3) {
    flex-shrink: 0;
  }
}

11.png

這時第一個元素的吸收寬度為: 11001100+2200100=20px\frac{1*100}{1*100+2*200}*100 = 20px,最終元素寬度為 10020=80px100-20=80px

這時第二個元素的吸收寬度為:22001100+2200100=80px\frac{2*200}{1*100+2*200}*100 = 80px,最終元素寬度為 20080=120px200-80=120px

這時第三個元素的 flex-shrink 值為 0,不吸收寬度,最終元素寬度即為元素本身的寬度 300px300px

flex 的簡寫值

一般我們很少見上述屬性單獨使用,都是用flex這一個簡寫屬性來表述元素的伸縮。

Flex 簡寫形式允許你把三個數值按這個順序書寫 flex-growflex-shrinkflex-basis。以下是常見的幾種取值:

  • flex: initial 的擴充套件為 0 1 auto (不可放大、可縮小、大小與容器元素大小一致)
  • flex: auto 的擴充套件為 1 1 auto (可放大、可縮小、大小與容器元素大小一致)
  • flex: none 的擴充套件為 0 0 auto (不可放大、不可縮小、大小與容器元素大小一致)
  • flex: <positive-number>的擴充套件為 <positive-number> 1 0

flex: <positive-number>的應用:

兩欄佈局

.two-grid-wrapper {
  display: flex;
  margin-top: 20px;
  height: 200px;
  .left {
    width: 200px;
    background-color: gold;
  }
  .right {
    flex: 1;
    background-color: tan;
  }
}

效果如下:左側寬度不變,右側自適應

12.png

三欄佈局

.three-grid-wrapper {
  display: flex;
  margin-top: 20px;
  height: 200px;
  .left {
    width: 200px;
    background-color: gold;
  }
  .right {
    width: 200px;
    background-color: gold;
  }
  .center {
    flex: 1;
    background-color: tan;
  }
}

效果如下:左右寬度不變,中間自適應

13.png

PS.flex 子元素沒有 positive free space 就不會增長;沒有 negative free space 就不會縮小。

結束語

學習八股文的時候發現自己對flex佈局很不熟悉,基本概念都說不上來,只會無腦用,於是去學習,然後就誕生了這篇文章。歡迎指正。

(學習視訊分享:)

以上就是一文詳解三個 flex 屬性對元素的影響的詳細內容,更多請關注TW511.COM其它相關文章!