1. 程式人生 > >CSS3中彈性盒子Flex使用詳解

CSS3中彈性盒子Flex使用詳解

在介紹flex之前,先說一個面試時關於CSS佈局常提到的問題,也就是三欄佈局,左右兩邊固定,中間一欄自適應螢幕大小,如下效果:

這裡寫圖片描述

以前常見的做法就是將左右兩邊絕對定位,定位到相應的位置,中間設定width:100%;然後在設定對應的padding-left和padding-right值。現在css3中提供了flex屬性,也就是彈性盒子佈局,這樣就很好地處理上面的問題,具體程式碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
利用flex固縮固佈局</title> <style> *{ margin: 0; padding-right: 0; } header{ width: 100%; height: 200px; margin-top: 10px; display: flex; display: -webkit-flex; } header div{ height
: 200px
; border: 1px solid red; margin: 0px 10px; }
header div:nth-child(1){ width: 100px; } header div:nth-child(2){ flex:1; -webkit-flex:1; } header div:nth-child(3){ width: 100px; }
</style> </head> <body> <header> <div>width:100px;</div> <div>寬度自適應</div> <div>width:100px;</div> </header> </body> </html>

上面程式碼中沒有涉及到一點定位的內容,僅僅在父容器中設定了display:flex;屬性,並在子元素中設定flex:1;即可。非常的方便。既然flex這麼強大,那麼接下來就介紹一下flex的具體使用方法。

flex容器

通過上面的程式碼,我們能發現:要使用flex佈局,需要設計到兩層,外面一層叫做Flex容器(flex container),簡稱”容器”。它的所有子元素自動成為容器成員,稱為Flex專案(flex item),簡稱”專案”。下面是一個flex佈局的基本概念介紹:

這裡寫圖片描述

容器預設存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。專案預設沿主軸排列。

大致瞭解了之後,主要還是怎麼用。flex容器有以下六個屬性:


 1. flex-direction
 2. flex-wrap
 3. flex-flow
 4. justify-content
 5. align-items
 6. align-content

下面逐個介紹一下這六個屬性的作用:

1、flex-direction

flex-direction屬性決定主軸的方向(即專案的排列方向)。

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

四個值分別代表:


 - row(預設值):主軸為水平方向,起點在左端。
 - row-reverse:主軸為水平方向,起點在右端。
 - column:主軸為垂直方向,起點在上沿。
 - column-reverse:主軸為垂直方向,起點在下沿。

效果分別對應如下:

這裡寫圖片描述

2、flex-wrap

flex-wrap屬性定義,如果一條軸線排不下,如何換行。有三個屬性值,預設情況下是wrap

flex-wrap: nowrap | wrap | wrap-reverse;

分別表示不換行、換行以及反轉換行,效果分別如下:

這裡寫圖片描述

3、flex-flow

flex-flow屬性是flex-direction屬性和flex-wrap屬性的簡寫形式,預設值為row nowrap。這裡就不再具體測試。

4、justify-content

justify-content屬性定義了專案在主軸上(即相當於X軸)的對齊方式。一共有五個屬性值:

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

分別表示:左對齊、右對齊、居中、兩端對齊、每個專案兩側的間隔相等。以下是對應的效果:

這裡寫圖片描述

5、align-items

align-items屬性定義專案在交叉軸上(即Y軸上)如何對齊。也有五個屬性值:

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

分表表示:上對齊、下對齊、居中對齊、專案的第一行文字的基線對齊、如果專案未設定高度或設為auto,將佔滿整個容器的高度(預設值)。

下面是對應的效果圖:

這裡寫圖片描述

6、align-content

align-content屬性定義了多根軸線的對齊方式。如果專案只有一根軸線,該屬性不起作用。該屬性定義多跟軸線在Y軸上的對齊方式,與align-items有點類似。其有以下六個屬性值:

 - flex-start:與交叉軸的起點對齊。
 - flex-end:與交叉軸的終點對齊。
 - center:與交叉軸的中點對齊。
 - space-between:與交叉軸兩端對齊,軸線之間的間隔平均分佈。
 - space-around:每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。
 - stretch(預設值):軸線佔滿整個交叉軸。

flex item

介紹完了flex容器,介紹就要介紹容器裡的成員了,Flex專案(flex item),簡稱”專案”。這裡需要之一的是:設為Flex佈局以後,子元素的float、clear和vertical-align屬性將失效。

flex專案有以下六個屬性:

 1. order
 2. flex-grow
 3. flex-shrink
 4. flex-basis
 5. flex
 6. align-self

以下對每一個分別進行介紹:

1、order

order屬性定義專案的排列順序。數值越小,排列越靠前,預設為0。有了這個屬性,可以調整在HTML中出現的順序。

order: <integer>;

這裡寫圖片描述

2、flex-grow

flex-grow屬性定義專案的放大比例,預設為0,即如果存在剩餘空間,也不放大。

flex-grow: <number>; /* default 0 */

如果一個專案的flex-grow屬性為2,另一個專案都為1,則前者佔據的剩餘空間將比後一項多一倍。如下所示:

這裡寫圖片描述

3、flex-shrink

flex-shrink屬性定義了專案的縮小比例,預設為1,即如果空間不足,該專案將縮小。

flex-shrink: <number>; /* default 1 */

如果所有專案的flex-shrink屬性都為1,當空間不足時,都將等比例縮小。如果一個專案的flex-shrink屬性為0,其他專案都為1,則空間不足時,前者不縮小。

這裡寫圖片描述

4、flex-basis

flex-basis屬性定義了在分配多餘空間之前,專案佔據的主軸空間(main size)。類似於設定了width屬性。

5、flex

flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫,預設值為0 1 auto。後兩個屬性可選。

6、align-self

align-self屬性允許單個專案有與其他專案不一樣的對齊方式,可覆蓋align-items屬性。預設值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch。

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

上面六個取值中,除了auto,其他值與align-items屬性完全一致。這裡就不一一介紹了。

flex的應用

利用flex,我們可以完成很多佈局,而且不需要太多的程式碼。開頭的聖盃佈局就是一種典型的示例,下面我們利用flex來實現流式佈局,並且加上簡單的媒體查詢,使其在移動端和PC顯示結構不一樣,程式如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>flex實現流式佈局</title>
    <style type="text/css">
    *{ margin: 0; padding:0;}
    .container{
        margin: 20px 20px;
        padding: 10px 10px;
        display: flex;
        flex-wrap:wrap;
        border: 1px solid #ADAAAA;
    }
      .item{
        flex:0 0 40%;
        height: 100px;
        margin:20px 5%;
        box-sizing: border-box;
        border: 1px solid red;
    }

    @media (min-width:960px){
     .item{
        flex:0 0 20%;
        height: 100px;
        margin:20px 2.5%;
        box-sizing: border-box;
        border: 1px solid red;
     }
    }
    </style>
</head>
<body>
    <div class="container">
        <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 class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>
</html>

在PC端顯示結果如下:

這裡寫圖片描述

在移動端顯示效果如下:

這裡寫圖片描述