1. 程式人生 > >響應式佈局:CSS3彈性盒flex佈局模型

響應式佈局:CSS3彈性盒flex佈局模型

頁面佈局一直都是web應用樣式設計的重點 
我們傳統的佈局方式都是基於盒模型的 
利用display、position、float來佈局有一定侷限性 
比如說實現自適應垂直居中 
隨著響應式佈局的流行,CSS3引入了更加靈活的彈性佈局模型

flex彈性佈局

使用彈性佈局可以有效的分配一個容器的空間 
即使我們的容器元素尺寸改變 
它內部的元素也可以調整它的尺寸來適應空間 

若想讓一個元素變成彈性盒 
很簡單

.demo { /*塊級元素*/
    display: flex;
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
.demo { /*行級元素*/
    display: inline-flex;
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

設定了flex佈局後,子元素的float、clear和vertical-align屬性就會失效

舉個小例子

<div class="flex-box">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
.flex-box {
    width: 500px;
    height: 100px;
    border: 1px solid black;
}
.flex-item {
    width: 100px;
    height
: 100px
; font-size: 80px; line-height: 100px; text-align: center; }
.flex-item:nth-child(1) { background-color: lightseagreen; } .flex-item:nth-child(2) { background-color: violet; } .flex-item:nth-child(3) { background-color: cornflowerblue; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

正常情況下,子元素div預設佔滿一行,所以他們只能縱向排列

現在我們使用彈性佈局

.flex-box {
    display: flex; /*增*/
    width: 500px;
    height: 100px;
    border: 1px solid black;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我們發現子元素在父元素中呈現行排列 
看起來好像子元素應用了浮動float 
但這個屬性遠遠沒有這麼簡單 
現在才剛剛開始(⊙▽⊙)

相關概念

在講那些屬性之前,我們先來看一些基本概念 
設定了flex佈局的元素,稱為“flex容器”,簡稱“容器” 
它的子元素,稱為“flex專案”,簡稱“專案” 
這裡我引入一張圖(原諒我的盜圖,自己懶得畫了..)

“容器”中有兩條垂直的座標軸 
橫向的叫做主軸 
縱向的叫做交叉軸 
主軸左邊與右邊分別叫做主軸起點主軸終點 
交叉軸上邊與下邊分別叫做交叉軸起點交叉軸終點

“專案”也有兩個名詞 
每個專案的寬與高叫做主軸尺寸交叉軸尺寸

這回我們就能理解了為什麼使用彈性佈局後子元素呈現行排列 
專案在容器中就是沿著主軸排列的

容器屬性

彈性盒佈局“容器”有如下屬性

  • flex-flowflex-directionflex-wrap
  • justify-content
  • align-items
  • align-content

flex-direction

我們可以使用flex-direction指定主軸的方向,從而改變專案的排列方向 
屬性值:

  • row(預設)
  • row-reverse
  • column
  • column-reverse
.flex-box {
    display: flex;
    width: 500px;
    height: 100px;
    border: 1px solid black;
    flex-direction: row-reverse; /*增*/
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

 
其他屬性也不多解釋了,很好理解

 
這張圖片分別對應了column-reverse、column、row、row-reverse

flex-wrap

我們彈性盒的專案預設都是排列在一個軸上的 
這樣如果專案多的話,會“彈性”壓縮在一行 
比如說我多加一些專案

我並沒有改變專案的寬 
但是由於處於彈性盒中專案過多,專案在主軸上被壓縮

現在新增flex-wrap屬性

.flex-box {
    ......
    flex-wrap: wrap; /*增*/
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

flex-wrap: wrap可以讓我們指定當容器“裝不下”專案時,是否換行 
屬性值如下:

  • no-wrap
  • wrap
  • wrap-reverse

前兩個我們都理解了 
第三個屬性值wrap-reverse 
換行的專案會排在上面像這樣 

flex-flow

flex-flow是flex-direction和flex-wrap的複合屬性 
兩個屬性都是必寫的 
就不多解釋了

justify-content

justify-content屬性定義了專案在主軸上的對齊方式 
屬性值如下:

  • flex-start:左對齊(預設)
  • flex-end:右對齊
  • center:居中
  • space-between:兩端對齊(專案間間隔相同)
  • space-around:兩端間隔對齊(專案間間隔是專案與邊框間隔的2倍)

flex-start : 

flex-end: 

center: 

space-between: 

space-around: 

align-items

align-items屬性定義專案在交叉軸上如何對齊 
屬性值如下:

  • stretch:未設定高度(或height: auto)的專案佔滿整個容器高度(預設)
  • flex-start :交叉軸起點對齊
  • flex-end:交叉軸終點對齊
  • center:交叉軸中點對齊
  • baseline:專案第一行文字的基線對齊

flex-start: 

flex-end: 

center: 

baseline: 

align-content

align-content屬性定義多根軸線的對齊方式 
這個屬性只有在容器有多條主軸是才有效,一條主軸無效 
類似於justify-content屬性 
屬性值如下:

  • stretch:軸線佔滿整個交叉軸(預設值)
  • flex-start:與交叉軸的起點對齊
  • flex-end:與交叉軸的終點對齊
  • center:與交叉軸的中點對齊
  • space-between:與交叉軸兩端對齊,軸線間間隔相等
  • space-around:每根軸線兩側的間隔都相等

flex-start: 

flex-end: 

center: 

space-between: 

space-around: 

專案屬性

彈性盒佈局“專案”有如下屬性

  • order
  • flexflex-growflex-shrinkflex-basis
  • align-self

order

order允許我們自定義專案的排列順序 
預設為0,屬性值是數字,數值越小越靠前 
有點類似我們優先佇列中的優先順序

.flex-item:nth-child(1) {
    ......
    order: 99;
}
.flex-item:nth-child(2) {
    ......
    order: -1;
}
.flex-item:nth-child(3) {
    ......
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

flex-grow

flex-grow定義專案的放大比例 
預設是0,就是如果沒有佔滿容器整行,也不放大專案,就像上面的圖片

.flex-item:nth-child(1) {
    ......
    flex-grow: 1; <--
}
.flex-item:nth-child(2) {
    ......
    flex-grow: 2; <--
}
.flex-item:nth-child(3) {
    ......
    flex-grow: 3; <--
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

這就相當於三個專案把剩下的空間“切成”6塊 
專案一拿走1塊,專案二拿走2塊,專案三拿走3塊

flex-shrink

flex-shrink定義專案的縮小比例 
預設是1,就是如果空間不足,該專案將等比縮小 
通過這個屬性我們可以控制各個專案縮小的比例

.flex-item:nth-child(1) {
    ......
    flex-shrink: 1; <--
}
.flex-item:nth-child(2) {
    ......
    flex-shrink: 2; <--
}
.flex-item:nth-child(3) {
    ......
    flex-shrink: 3; <--
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

這樣各個專案縮小的比例就是 1:2:3 
從而保證所有專案總寬度和容器寬度相等

flex-basis

flex-basis定義在分配多餘空間之前,專案佔據的主軸空間 
預設auto,就是專案本來的寬度 
我們可以手動設定長度

.flex-item:nth-child(1) {
    ......
    flex-basis: 150px; <--
}
.flex-item:nth-child(2) {
    ......
}
.flex-item:nth-child(3) {
    ......
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

flex

flex是flex-grow、flex-shrink、flex-basis的複合屬性 
預設值:0 1 auto,後兩個屬性可選 
可以寫關鍵字:auto (1 1 auto) 和 none (0 0 auto)

align-self

align-self屬性允許個別專案擁有與眾不同的對齊方式 
就是會覆蓋align-items設定的對齊屬性 
預設值auto,繼承彈性容器的align-items屬性值 
屬性值除了auto外,和align-items一樣,就不多解釋了

  • auto
  • stretch
  • flex-start
  • flex-end
  • center
  • baseline
.flex-box {
    ......
    align-items: center;
}
.flex-item:nth-child(2) {
    ......
    align-self: flex-end;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

彈性盒的全部屬性就是這些了 
其實這些都是最新的語法 
在此之前瀏覽器的實現都不一致,瞭解一下就好了

  • 2009年規範語法: 
    display: box
  • 2011年非官方規範語法: 
    display: flexbox
  • 最新版本規範語法: 
    display: flex