flex 佈局

qianyin925發表於2018-12-08

瀏覽器支援

flex 佈局

描述

  • FlexFlexible Box 的縮寫,意為”彈性佈局”,用來為盒狀模型提供最大的靈活性。
  • 採用 Flex 佈局的元素(設定 display: flex || inline-flex 的元素 ),稱為 Flex 容器(flex container),簡稱”容器”。它的所有子元素自動成為容器成員,稱為 Flex 專案(flex item),簡稱”專案”。

建立彈性容器

  • 為容器設定樣式: display: flex || inline-flex 即可使容器升級為彈性容器
  • 當將容器設為 Flex 佈局以後,容器內的所有專案的 floatclearvertical-align 屬性將失效(佈局重置)。

在彈性容器中,專案將消除塊元素特性

  • 將容器設為 Flex 佈局以後, 容器內的塊級元素(display: block)將不再具有塊級元素的特性(當然其 display 值還是 block);

  • 有如下演示程式碼

  #wrapper{
    display: flex;
    background: #eee;
    padding: 10px;
  }
  .item{
    width: 50px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1{background:brown}
  .item-2{background:pink}
  .item-3{background:orchid}
複製程式碼
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>
複製程式碼
  • 圖中專案不再具有塊級元素的特性(有點類似 inline-block

flex 佈局

在彈性容器中專案的 margin 在垂直方向上的值不會進行疊加

  • 如下程式碼:
  <style>
    *{padding: 0; margin: 0;}
    #wrapper{
     display: flex;
     width: 110px;
     flex-wrap: wrap;
    }
    .item{
      width: 40px;
      height: 40px;
      margin: 5px;
      background: red;
      line-height: 40px;
      text-align: center;
    }
  </style>
  <div id="wrapper">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
  </div>
複製程式碼
  • 程式碼效果圖

flex 佈局

主軸和交叉軸

  • 容器預設存在兩根軸: 主軸(專案沿主軸進行一一排列)、交叉軸(垂直於主軸)
  • 主軸的開始位置(與邊框的交叉點)叫做 main start,結束位置叫做 main end
  • 交叉軸的開始位置叫做 cross start,結束位置叫做 cross end
  • 單個專案佔據的主軸空間叫做 main size,佔據的交叉軸空間叫做 cross size

flex 佈局

容器屬性

屬性 描述  
flex-direction 決定主軸的方向(即專案的排列方向)
flex-wrap 決定當一條軸線排不下所有專案時如何進行換行(當專案多行時變相決定行的排列方向)
flex-flow flex-direction屬性和flex-wrap屬性的簡寫形式
justify-content 定義專案在主軸方向上的對齊方式
align-content 專案一一進行排列必然形成行, 該屬性則定義了行(軸線)在交叉軸上的對齊方式
align-items 定義行內(單軸內)所有專案在交叉軸方向上的對齊方式

flex-direction: row | row-reverse | column | column-reverse

  • flex-direction 屬性決定主軸的方向(即專案的排列方向)。主軸的方向決定了交叉軸的方向(交叉軸垂直於主軸);
  • 主軸具有四個屬性對應四個主軸方向; 但是交叉軸只有兩個方向要麼從左向右要麼就是從上到下;
屬性值  描述
 row 從左向右(預設值)
 row-reverse 和 row 屬性相反,即從右向左
 column 從上到下
 column-reverse 和 column 相反,即從下到上
  • flex-direction 屬性不同取值, 容器內專案的排列順序:

flex 佈局

  • 下面程式碼分別修改容器 flex-direction 屬性的取值將得到上文演示圖片的效果
#wrapper{
  display: flex;
  flex-direction: row;
  width: 200px;
  height: 200px;
  background: #eee;
  padding: 10px;
}
.item{
  width: 50px;
  height: 50px;
  text-align: center;
  line-height: 50px;
}
.item-1{background:brown}
.item-2{background:pink}
.item-3{background:orchid}
複製程式碼
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>
複製程式碼

flex-wrap: nowrap | wrap | wrap-reverse

  • 預設情況下,專案都排在一條線(又稱”軸線”)上。flex-wrap 屬性決定了當一條軸線排不下所有專案的情況下,如何進行換行。
屬性值 描述
nowrap 不進行換行(預設值)
wrap 允許換行, 沿著交叉軸方向進行排列
wrap-reverse 允許換行, 並沿著交叉軸相反方向進行排列
  • 如下圖, 預設情況(flex-wrap: nowrap)下專案都排在一條線(又稱”軸線”)上; 即使一行無法排列所有的專案,也會對專案在主軸方向上的大小進行縮放迫使所有專案都能夠在一行進行排列
  • 補充: 至於專案如何進行縮放, 則取決於專案的 flex-shrink 屬性, 該屬性後續會進行講解

flex 佈局

  • 上圖演示程式碼
<style>
  #wrapper{
    display: flex;
    flex-direction: row;
    width: 200px;
    height: 200px;
    background: #eee;
    padding: 10px;
  }
  .item{
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1{background:brown}
  .item-2{background:pink}
  .item-3{background:orchid}
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>
複製程式碼
  • flex-wrap: wrap 當所有專案無法在一行進行排列時,允許換行進行排序,行的排列順序為交叉軸的方向;
  • 如下程式碼:
 <style>
  #wrapper{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 200px;
    background: #eee;
    padding: 10px;
  }
  .item{
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1{background:brown}
  .item-2{background:pink}
  .item-3{background:orchid}
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>
複製程式碼

flex 佈局

  • flex-wrap: wrap-reverse 當所有專案無法在一行進行排列時,允許換行進行排序,行的排列順序和交叉軸的方向相反;
  • 如下演示程式碼:
<style>
  #wrapper{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap-reverse;
    width: 200px;
    background: #eee;
    padding: 10px;
  }
  .item{
    width: 100px;
    height: 50px;
    text-align: center;
    line-height: 50px;
  }
  .item-1{background:brown}
  .item-2{background:pink}
  .item-3{background:orchid}
</style>
<div id="wrapper">
  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
</div>
複製程式碼
  • 如圖:交叉軸的方向從上到下, 專案換行排序的方向和交叉軸相反從下到上

flex 佈局

flex-flow

flex-flow 屬性是 flex-direction 屬性和flex-wrap屬性的簡寫形式,預設值為 row nowrap。

justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly

  • justify-content 屬性定義了專案在主軸上的對齊方式。
屬性值 描述
flex-start 專案在主軸上向主軸開始方向靠攏(預設值)
flex-end 專案在主軸上向主軸結束方向靠攏
center 專案在主軸上全部往中間靠攏
space-between 設定主軸方向多餘空間的處理方式(具體看圖)
space-around 設定主軸方向多餘空間的處理方式(具體看圖)
space-evenly 設定主軸方向多餘空間的處理方式(具體看圖)
  • justify-content 不同屬性值在主軸方向上的排列演示圖

flex 佈局

  • 下面程式碼分別修改容器 justify-content 屬性值將得到上文演示圖片的效果
  <style>
    #wrapper{
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      width: 200px;
      height: 200px;
      background: #eee;
    }
    .item{
      width: 50px;
      height: 50px;
      text-align: center;
      line-height: 50px;
    }
    .item-1{background:brown}
    .item-2{background:pink}
    .item-3{background:orchid}
  </style>
  <div id="wrapper">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
  </div>
複製程式碼

align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch

  • 專案沿主軸排列成一行或者多行, align-content 屬性則定義這些行在交叉軸上的對齊方式(設定行(軸線)的對齊方式)
屬性值 描述
flex-start 每行都向交叉軸起點靠攏 
flex-end 每行都向交叉軸終點靠攏 
center 每行都向交叉軸中間靠攏 
space-between 設定交叉軸方向多餘空間的處理方式(具體看圖)
space-around 設定交叉軸方向多餘空間的處理方式(具體看圖)
space-evenly 設定交叉軸方向多餘空間的處理方式(具體看圖)
stretch (預設值)每行都在交叉軸方法進行均勻伸縮,企圖佔滿交叉軸上所有剩餘的空間
  • align-content 不同屬性值, 行在交叉軸方向上的排列演示圖

flex 佈局

  • 下面程式碼依次修改 align-content 屬性值將得到上文演示圖的效果
  • 補充:對比程式碼和示意圖,其實我們並沒有給每個專案設定高度,但是專案卻自動伸縮獲取 100% 的高度,這是因為 align-items 的預設值為 stretch , align-items 在下文會進詳細的說明;
  <style>
    #wrapper{
      width: 200px;
      height: 200px;
      background: #eee;
      display: flex;
      flex-wrap: wrap;
      align-content: flex-start;
    }
    .item{
      width: 40px;
      line-height: 40px;
      margin: 1px;
      background: red;
      text-align: center;
    }
    .item-50h{line-height: 50px; }
    .item-70h{line-height: 70px; }
    .item-30h{line-height: 30px; }
  </style>
  <div id="wrapper">
    <div class="item item-50h">1</div>
    <div class="item item-70h">2</div>
    <div class="item item-30h">3</div>
    <div class="item item-50h">4</div>
    <div class="item item-70h">5</div>
    <div class="item item-30h">6</div>
  </div>
複製程式碼

align-items: flex-start | flex-end | center | baseline | stretch

  • 專案沿主軸進行排列成一行或者多行, align-content 則可以設定每行在交叉軸方向的對齊方式
  • align-items 則設定行內所有專案在該行內沿著交叉軸方法的對齊方式
屬性值 描述
flex-start 行內專案在交叉軸上向開始位置靠攏
flex-end 行內專案在交叉軸上向結束位置靠攏
center 行內專案在交叉軸上向中間位置靠攏
basline 行內專案按照文字基線進行對齊(用於不同字型大小、行高的文字佈局上特別好用)
stretch (預設)行內專案(在未為專案設定高度或者設為 auto 情況下)在交叉軸方法進行伸縮,佔滿該行在交叉軸上的所有剩餘空間
  • align-items 不同屬性值, 行內專案在交叉軸方向上的排列示意圖

flex 佈局

  • 上文示意圖程式碼:依次修改 align-center 屬性值將得上上文示意圖的效果
  • 注意對比程式碼和示意圖,發現 baslinecenter 效果貌似一樣, 實際上是因為所有專案設定了相同的字型大小、並且文字居中;有興趣的可以嘗試移除行高併為每個專案設定不同的字型大小,檢視 baseline 的具體效果;
  <style>
    #wrapper{
      width: 200px;
      height: 200px;
      background: #eee;
      display: flex;
      flex-wrap: wrap;
      align-content: flex-start;
      align-items: stretch;
    }
    .item{
      width: 40px;
      line-height: 40px;
      margin: 1px;
      background: red;
      text-align: center;
    }
    .item-50h{line-height: 50px; }
    .item-70h{line-height: 70px; }
    .item-30h{line-height: 30px; }
  </style>
  <div id="wrapper">
    <div class="item item-50h">1</div>
    <div class="item item-70h">2</div>
    <div class="item item-30h">3</div>
    <div class="item item-50h">4</div>
    <div class="item item-70h">5</div>
    <div class="item item-30h">6</div>
  </div>
複製程式碼

專案屬性:

屬性 描述
order 定義專案的排列順序
flex-grow 定義專案的放大比例
flex-shrink 定義專案的縮小比例
flex-basis 定義了在分配多餘空間之前,專案佔據的主軸空間
flex flex-grow flex-shrink flex-basis 的簡寫屬性
align-self 允許單個專案有與其他專案不一樣的對齊方式,可覆蓋 align-items 屬性(重新設定該專案的 align-items 屬性 )

order: <integer>

  • order 屬性定義專案的排列順序。數值越小,排列越靠前,預設為0。(支援負數)
  • 有程式碼如下:
  <style>
    #wrapper{
      display: flex;
      flex-direction: row;
      width: 200px;
      height: 200px;
      background: #eee;
    }
    .item{
      width: 50px;
      line-height: 50px;
      height: 50px;
      text-align: center;
    }
    .item-1{background:brown; order: 3}
    .item-2{background:pink; order: 1}
    .item-3{background:orchid; order: -1}
  </style>
  <div id="wrapper">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
  </div>
複製程式碼
  • 演示效果有:

flex 佈局

flex-grow: <number>

  • 已只專案是沿著主軸的方向進行排列的,當專案較少時, 主軸方法存在剩餘的空間時; 可通過 flex-grow 來規定如何處理主軸方向上剩餘的空間;

  • 主軸上剩餘空間的計算則取決於 flex-basis (下面介紹)

  • flex-grow 屬性的預設值為 0,即如果存在剩餘空間,也不進行放大(不對剩餘的空間進行處理)。

  • 如果所有專案的 flex-grow 屬性值都相等(假如都為 1 ),則它們將等分剩餘空間(如果有的話)。

  • 如果一個專案的 flex-grow 屬性為2,其他專案都為1,則前者佔據的剩餘空間將比其他項多一倍(按 2:1 的比例分配剩餘空間)。

  • flex-grow 屬性演示圖

flex 佈局

  • 下面程式碼中只需修改每個專案的 flex-grow 屬性值即可得到上述效果
  <style>
    #wrapper{
      display: flex;
      flex-direction: row;
      width: 400px;
      height: 200px;
      background: #eee;
    }
    .item{
      width: 50px;
      line-height: 50px;
      height: 50px;
      text-align: center;
    }
    .item-1{background:brown; flex-grow: 2}
    .item-2{background:pink; flex-grow: 1}
    .item-3{background:orchid; flex-grow: 1}
  </style>
  <div id="wrapper">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
  </div>
複製程式碼

flex-shrink: <number>

  • 已知在專案沿主軸進行排序時, 當主軸無法容下所有專案並且主軸方向上專案的排列不允許進行換行的情況下所有專案會進行等比例進行縮放,而這一行為實際上是由專案的 flex-shrink 屬性進行控制的; 因為 flex-shrink 屬性定義了專案的縮小比例;

  • 如果所有專案的 flex-shrink 屬性都為 1,當空間不足時,都將等比例縮小(預設情況, 所以也就有了上述情況)。

  • 如果一個專案的 flex-shrink 屬性為 0, 其他專案都為 1,則空間不足時,前者不縮小, 後者等比例進行縮放。

  • 如果一個專案的 flex-shrink 屬性為 2 ,其他專案都為 1,則空間不足時,前者和後者按照 2:1 進行縮小;

  • 負值對該屬性無效。

  • flex-shrink 屬性演示圖

flex 佈局

  • 下面程式碼中只需要修改 flex-shrink 即可實現上述效果
  <style>
    #wrapper{
      display: flex;
      flex-direction: row;
      width: 400px;
      height: 200px;
      background: #eee;
    }
    .item{
      width: 200px;
      line-height: 50px;
      height: 50px;
      text-align: center;
    }
    .item-1{background:brown; flex-shrink: 2}
    .item-2{background:pink; flex-shrink: 1}
    .item-3{background:orchid; flex-shrink: 1}
  </style>
  <div id="wrapper">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
  </div>
複製程式碼

flex-basis: <length>

  • flex-grow 屬性生效(分配多餘主軸空間)之前, flex-basis 屬性將設定專案所佔據的基礎主軸空間( 相當於設定專案的最小寬度 )

  • 瀏覽器實際上是根據 flex-basis 屬性來計算主軸上的剩餘空間(只是 flex-basis 預設值為 auto 等於專案的大小);

  • flex-basis 屬性演示圖

flex 佈局

  • 上文演示圖程式碼:
  <style>
    #wrapper{
      display: flex;
      flex-direction: row;
      width: 800px;
      height: 200px;
      background: #eee;
    }
    .item{
      width: 50px;
      line-height: 50px;
      height: 50px;
      text-align: center;
    }
    .item-1{background:brown; flex-grow: 1; flex-basis: 400px}
    .item-2{background:pink; flex-grow: 1;}
    .item-3{background:orchid; flex-grow: 1;}
  </style>
  <div id="wrapper">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
  </div>
複製程式碼

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

  • flex 屬性是 flex-grow, flex-shrinkflex-basis 的簡寫,預設值為 0 1 auto 。後兩個屬性(flex-shrinkflex-basis)可選。
  • 該屬性有兩個快捷值:
    • auto: 等價於 flex:1 1 auto
    • none: 等價於 flex: 0 0 auto
  • 建議優先使用 flex 屬性,而不是單獨寫三個分離的屬性( flex-grow, flex-shrinkflex-basis ),因為瀏覽器會推算相關值。

align-self: auto | flex-start | flex-end | center | baseline | stretch

  • 還記得在 flex 容器中我們可以通過 align-items 屬性來設定行內專案在交叉軸上的對齊方式, 那麼如果需要行內某個專案具有鶴立獨行的對齊方式時就可以通過為專案設定 align-self 來修改(覆蓋)行內專案在交叉軸上的對齊方式

  • align-self 屬性演示

flex 佈局

  • 演示程式碼如下:
  <style>
    #wrapper{
      width: 200px;
      height: 200px;
      background: #eee;
      display: flex;
      flex-wrap: wrap;
      align-content: flex-start;
      align-items: flex-start;
    }
    .item{
      width: 40px;
      line-height: 40px;
      margin: 1px;
      background: red;
      text-align: center;
    }
    .item-50h{line-height: 50px; }
    .item-70h{line-height: 70px; }
    .item-30h{line-height: 30px;  align-self: flex-end;}
  </style>
  <div id="wrapper">
    <div class="item item-50h">1</div>
    <div class="item item-70h">2</div>
    <div class="item item-30h">3</div>
    <div class="item item-50h">4</div>
    <div class="item item-70h">5</div>
    <div class="item item-30h">6</div>
  </div>
複製程式碼

flex 佈局的一些小例子

骰子佈局

單個專案在 flex 容器中的定位佈局

  • 效果演示:

flex 佈局

  • 演示程式碼有(依次修改 flex 容器 justify-content 和 align-items 屬性值):
  <style>
    body{padding: 50px}
    #wrapper{
      background: #eee;
      margin: 5px;
      width: 240px;
      height: 240px;
    }
    .item{
      width: 80px;
      height: 80px;
      background: red;
    }
    .flex{
      display: flex;
      justify-content: flex-start;
      align-items: flex-start;
    }
  </style>
  <div id="wrapper" class="flex">
    <div class="item"></div>
  </div>
複製程式碼
  • 上面的效果實際上是對 justify-content 和 align-items 屬性的 flex-start center flex-end 三個屬性的組合

雙專案以及三專案在 flex 容器中簡單佈局

  • 簡單演示

flex 佈局

  • 演示程式碼
  <style>
    body{padding: 50px}
    #box{
      display: flex;
      flex-wrap: wrap;
      width: 750px;
    }
    .wrapper{
      background: #eee;
      margin: 5px;
      width: 240px;
      height: 240px;
    }
    .item{
      width: 70px;
      height: 70px;
      line-height: 70px;
      margin: 5px;
      text-align: center;
      background: red;
    }

    /* 雙專案 */
    .flex:nth-child(1){
      display: flex;
      justify-content: flex-start;
    }
    .flex:nth-child(2){
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
    }
    .flex:nth-child(3){
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
    }
    .flex:nth-child(3) .item:nth-child(2){
      align-self: center;
    }
    /* 三專案 */
    .flex:nth-child(4){
      display: flex;
      justify-content: flex-start;
    }
    .flex:nth-child(5){
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
    }
    .flex:nth-child(6){
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
    }
    .flex:nth-child(6) .item:nth-child(2){
      align-self: center;
    }
    .flex:nth-child(6) .item:nth-child(3){
      align-self: flex-end;
    }

  </style>
</head>
<body>
  <div id="box">
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
    </div>
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
    </div>
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
    </div>
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
  </div>
複製程式碼

四專案在 flex 容器中簡單佈局

  • 演示效果

flex 佈局

  • 演示程式碼
  <style>
    body{padding: 50px}
    #box{
      display: flex;
      flex-wrap: wrap;
      width: 750px;
    }
    .wrapper{
      background: #eee;
      margin: 5px;
      width: 240px;
      height: 240px;
    }
    .item{
      width: 70px;
      height: 70px;
      line-height: 70px;
      margin: 5px;
      text-align: center;
      background: red;
    }

    .flex:nth-child(1){
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-end;
      align-content: space-between;
    }
    .flex:nth-child(2){
      display: flex;
      flex-direction: column;
      justify-content: space-between;
    }
    .row{
      display: flex;
      justify-content: space-between;
    }
  </style>
  <div id="box">
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
    </div>
    <div class="wrapper flex">
      <div class="row">
        <div class="item">1</div>
        <div class="item">2</div>
      </div>
      <div class="row">
        <div class="item">3</div>
        <div class="item">4</div>
      </div>
    </div>
  </div>
複製程式碼

六專案九專案簡單佈局

  • 演示效果

flex 佈局

  • 演示程式碼(實際就是對專案進行分組巢狀)
  <style>
    body{padding: 50px}
    #box{
      display: flex;
      flex-wrap: wrap;
      width: 750px;
    }
    .wrapper{
      background: #eee;
      margin: 5px;
      width: 240px;
      height: 240px;
    }
    .item{
      width: 70px;
      height: 70px;
      line-height: 70px;
      margin: 5px;
      text-align: center;
      background: red;
    }

    /* 雙專案 */
    .flex:nth-child(1){
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      align-content: space-between;
    }
    .flex:nth-child(2){
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }
    .row{
      display: flex;
      width: 100%;
      justify-content: space-between;
    }
    .row:nth-child(2){
      justify-content: center;
    }
  </style>
  <div id="box">
    <div class="wrapper flex">
      <div class="row">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
      </div>
      <div class="row">
        <div class="item">4</div>
      </div>
      <div class="row">
        <div class="item">5</div>
        <div class="item">6</div>
      </div>
    </div>
    <div class="wrapper flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
      <div class="item">6</div>
      <div class="item">7</div>
      <div class="item">8</div>
      <div class="item">9</div>
    </div>
  </div>
複製程式碼

文字佈局(不同字型大小)

  • 演示效果

flex 佈局

  • 演示程式碼
  <style>
    body{padding: 50px}
    #wrapper{
      display: inline-flex;
      padding: 0 10px;
      height: 60px;
      background: red;
    }
    .no{font-size: 30px;}
    .order{font-size: 60px;}
    .line{ 
      border-left: 2px solid #333; 
      height: 40px;
      margin: 0 10px;
      align-self: center;
    }
    .row-left{
      display: flex;
      align-items: baseline;
    }
    .row-right{
      height: 100%;
      font-size: 18px;
      text-align: center;
      display: flex;
      flex-direction: column;
      justify-content: space-evenly;
    }
  </style>
  <div id="wrapper">
    <div class="row-left">
      <div class="no">No.</div>
      <div class="order">04</div>
    </div>
    <div class="line"></div>
    <div class="row-right">
      <div>十月</div>
      <div>2018</div>
    </div>
  </div>
複製程式碼

超級簡單的網格佈局

每個子項平局分佈容器的寬度(關鍵: flex-grow 屬性)

  • 演示效果

flex 佈局

  • 演示程式碼
  <style>
    body{padding: 50px}
    #wrapper{
      background: #eee;
      padding: 5px;
    }
    .item{
      height: 50px;
      line-height: 50px;
      text-align: center;
      background: red;
    }
    .grid{
      display: flex;
    }
    .grid-cell{
      /* 推薦使用簡寫屬性 flex: 1 */
      flex-grow: 1;
      margin: 5px;
    }
  </style>
  <div id="wrapper">
    <div class="grid">
      <div class="grid-cell item">1/2</div>
      <div class="grid-cell item">1/2</div>
    </div>
    <div class="grid">
      <div class="grid-cell item">1/3</div>
      <div class="grid-cell item">1/3</div>
      <div class="grid-cell item">1/3</div>
    </div>
    <div class="grid">
      <div class="grid-cell item">1/4</div>
      <div class="grid-cell item">1/4</div>
      <div class="grid-cell item">1/4</div>
      <div class="grid-cell item">1/4</div>
    </div>
    <div class="grid">
      <div class="grid-cell item">1/5</div>
      <div class="grid-cell item">1/5</div>
      <div class="grid-cell item">1/5</div>
      <div class="grid-cell item">1/5</div>
      <div class="grid-cell item">1/5</div>
    </div>
  </div>
複製程式碼

個別子項具有固定寬度其餘專案平均分佈(關鍵: flex-grow flex-basis 屬性)

  • 演示效果

flex 佈局

  • 演示程式碼
  <style>
    body{padding: 50px}
    #wrapper{
      background: #eee;
      padding: 5px;
    }
    .grid{
      display: flex;
    }
    .grid-cell{
      height: 50px;
      margin: 5px;
      line-height: 50px;
      text-align: center;
      background: red;
    }
    .grid:nth-child(1) .grid-cell{flex: 1;}
    .grid:nth-child(1) .grid-cell:nth-child(1){
      flex: 0 0 50%;
    }

    .grid:nth-child(2) .grid-cell{flex: 1;}
    .grid:nth-child(2) .grid-cell:nth-child(1){
      flex: 0 0 400px;
    }

    .grid:nth-child(3) .grid-cell{flex: 1;}
    .grid:nth-child(3) .grid-cell:nth-child(1){
      flex: 0 0 20%;
    }
    .grid:nth-child(3) .grid-cell:nth-child(4){
      flex: 0 0 20%;
    }

    .grid:nth-child(4) .grid-cell{flex: 1;}
    .grid:nth-child(4) .grid-cell:nth-child(1){
      flex: 0 0 200px;
    }
    .grid:nth-child(4) .grid-cell:nth-child(5){
      flex: 0 0 200px;
    }
  </style>
  <div id="wrapper">
    <div class="grid">
      <div class="grid-cell">50%</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">平均分佈</div>      
    </div>
    <div class="grid">
      <div class="grid-cell">400px</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">平均分佈</div>
    </div>
    <div class="grid">
      <div class="grid-cell">20%</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">20%</div>
    </div>
    <div class="grid">
      <div class="grid-cell">200px</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">平均分佈</div>
      <div class="grid-cell">200px</div>
    </div>
  </div>
複製程式碼

聖盃佈局

  • 聖盃佈局(Holy Grail Layout)指的是一種最常見的網站佈局。頁面從上到下,分成三個部分:頭部(header),軀幹(body),尾部(footer)。其中軀幹又水平分成三欄,從左到右為:導航、主欄、副欄。

  • t同時這裡我們滿足當螢幕寬度小於 785px 時軀幹從水平佈局變為垂直分佈, 從上到下依次是:航、主欄、副欄。

  • 演示效果

flex 佈局

  • 演示程式碼
  <style>
    body{padding: 50px}
    #wrapper{
      display: flex;
      flex-direction: column;
    }
    .row{ flex-grow: 1;}
    .header, .footer{background: #eee; line-height: 50px;text-align: center;}
    .body{ display: flex; height: 400px;}
    .left{flex: 0 0 12em; background: red;}
    .content{flex: 1;background: brown;}
    .right{flex: 0 0 12em; background: blue;}
    @media (max-width: 768px){
      .body{ display: flex; height: 400px; flex-direction: column;}
      .left{flex: auto; background: red;}
      .content{flex: auto;background: brown;}
      .right{flex: auto; background: blue;}
    }
  </style>
  <div id="wrapper">
    <div class="row header">#header</div>
    <div class="row body">
      <div class="left">#left</div>
      <div class="content">#content</div>
      <div class="right">#right</div>
    </div>
    <div class="row footer">#footer</div>
  </div>
複製程式碼

輸入框佈局

  • 常見輸入框帶前字尾,且自適應:
  • 效果演示

flex 佈局

  • 演示程式碼
  <style>
    body{
      padding: 50px;
    }
    #wrapper{
      display: flex; 
      border: 1px solid #eee;
      border-radius: 6px;
      line-height: 50px;
    }
    .prefix, .suffix{
      padding: 0 20px;
      background: #eee;
    }
    .input{flex:1; padding: 0 10px;}

  </style>
  <div id="wrapper">
    <div class="prefix">prefix</div>
    <div class="input">input</div>
    <div class="suffix">suffix</div>
  </div>
複製程式碼

圖文佈局

  • 圖文左右佈局,圖片和文字的任意對齊
  • 效果演示

flex 佈局

  • 演示程式碼:(修改 align-self 屬性可控制圖片和文字的對齊方式)
  <style>
    body{
      padding: 50px;
    }
    #wrapper{
     display: flex;
     align-items: flex-start;
    }
    .img{
      line-height: 50px;
      text-align: center;
      margin: 0 5px;
      flex: 1 0 50px;
      background: red;
      /* align-self: center; */
    }
  </style>
</head>
<body>
  <div id="wrapper">
    <div class="img">img</div>
    <div class="">
      Ubuntu Phone has been designed with obsessive attention to detail. 
      Form follows function throughout, from the ever-changing welcome 
      screen to essentials like messaging and alarms. And the Launcher 
      puts it all at your fingertips, whatever you’re doing with your phone.
      Canonical is the global software vendor that provides commercial, design
      and engineering support to the Ubuntu project. Today, our hardware 
      enablement team supports the pre-installation of Ubuntu on more 
      than 10% of all new PCs shipped, worldwide.
    </div>
  </div>
複製程式碼

流式佈局

  • 效果演示:

flex 佈局

  • 演示程式碼:
  <style>
    body{
      padding: 50px;
    }
    #wrapper{
     display: flex;
     flex-wrap: wrap;
     align-content: flex-start;
    }
    .item{
      width: 100px;
      height: 100px;
      margin: 5px;
      background: red;
    }

  </style>
  <div id="wrapper">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
複製程式碼

底部固定

  • 在某些頁面中有時頁面內容太少,無法佔滿一屏的高度,底欄經常就會抬高到頁面的中間, 下面使用flex實現底部固定在頁面底部上;

  • 效果演示

flex 佈局

  • 演示程式碼
  <style>
    *{padding: 0; margin: 0;}
    #wrapper{
     display: flex;
     height: 100vh;
     box-sizing: border-box;
     flex-direction: column;
    }
    .header{
      line-height: 50px;
      text-align: center;
      background: #eee;
    }
    .content{
      flex: 1;
      text-align: center;
    }
    .footer{
      line-height: 50px;
      text-align: center;
      background: #eee;
    }
  </style>
  <div id="wrapper">
    <div class="header">#header</div>
    <div class="content">#content</div>
    <div class="footer">#footer</div>
  </div>
複製程式碼