1. 程式人生 > >深入理解彈性盒flex佈局

深入理解彈性盒flex佈局

1. 前言

flex彈性盒,是一種佈局方式,當頁面需要適應不同的螢幕大小以及裝置型別時,它依然能確保元素

擁有更恰當的排布行為,彈性盒屬於 CSS 3 部分,IE9 以下不支援,現代瀏覽器指的就是 IE9 及以上的瀏覽器

2. flex的優勢

舉個例子:這裡我們要實現一個功能,讓一個dom元素水平垂直居中;

2.1 傳統實現方式(1),居中元素的寬高已知
    .box1{
            position: relative;
            background: darkcyan;
            width: 800px;
            height: 300px;
    }
    
    .box1-son{
        position: absolute;
        border: 1px solid seashell;
        width: 200px;
        height: 200px;
        top: 50%;
        left: 50%;
        transform: translate(-100px,-100px);
    }
    
    <div class="box1">
        <div class="box1-son">傳統佈局1</div>
    </div>
2.2 傳統實現方式(2),居中元素的寬高未知
    .box2{
        position: relative;
        background: darkcyan;
        width: 800px;
        height: 300px;
        
    }
    
    .box2-son{
        position: absolute;
        border: 1px solid seashell;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
    }


    <div class="box2">
        <div class="box2-son">傳統佈局2</div>
    </div>

當然這種方式同時以可以實現方式一的功能

2.3 flex方式實現
    .flex-container {
        background-color: #FECE3F;
        width: 600px;
        height: 220px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    .flex-item {
        width: 120px;
        height: 120px;
        background-color: blue;
    }

這種方式很簡單,我們只需要給容器新增三個屬性即可,即:

    display: flex;
    justify-content: center;
    align-items: center;

就是這麼簡單,display: flex表示容器為彈性盒,justify-content: center表示子元素在主軸方向居中,align-items: center表示子元素在側軸方向居中;

這裡的主軸和側軸不理解沒關係,請看下面介紹;

3. flex的基本理解

首先理解flex的幾個概念:

  1. 彈性容器 (Flex container)即父容器,包含著彈性專案的父元素,通過設定 display 屬性的值為 flex
    來定義彈性容器;
  2. 彈性專案 (Flex item)即子容器,彈性容器的每個子元素都稱為彈性專案;
  3. 一個彈性容器可以包含多個彈性專案,但是一個彈性專案 只有一個直接彈性容器;
  4. 主軸 (main axis)和側軸 (cross axis,也稱交叉軸),彈性專案依次排列的軸為主軸,與其垂直的那根軸為側軸,flex預設水平方向為主軸
  5. 我們可以通過改變彈性容器的flex-direction屬性來改變它的主軸方向
  6. flex 佈局涉及到 12 個 CSS 屬性(不含 display: flex),其中父容器、子容器各 6 個。不過常用的屬性只有 4 個,父容器、子容器各 2 個;

logo of vue-awesome repository

4. 父容器的屬性 共6個

前兩個為常用屬性,我們先說常用的

- justify-content   
- align-items       
- flex-direction
- flex-wrap
- flex-flow
- align-content
4.1 justify-content

該屬性定義了子容器在主軸上的排列對齊方式。它有5個取值

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

flex-start(預設值):左對齊
flex-end:右對齊
center: 居中
space-between:兩端對齊,專案之間的間隔都相等。
space-around:每個專案兩側的間隔相等。所以,專案之間的間隔比專案與邊框的間隔大一倍。

justify-content

4.2 align-items

該屬性定義了子容器在側軸上的排列對齊方式。它有5個取值

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

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

align-items

4.3 flex-direction

該屬性指定了內部元素是如何在 flex 容器中佈局的,定義了主軸的方向(正方向或反方向)

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

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

flex-direction

4.4 flex-wrap

flex-wrap屬性定義,如果一條軸線排不下,如何換行

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

nowrap(預設):不換行。
wrap:換行,第一行在上方。
wrap-reverse:換行,第一行在下方。
4.5 flex-flow

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

4.6 align-content

align-content屬性定義了多根軸線的對齊方式。如果專案只有一根軸線,該屬性不起作用。

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

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

align-content

5. 子容器屬性 共6個

前兩個為常用的屬性,我們先說常用的屬性

- flex
- align-self
- order
- flex-grow
- flex-shrink
- flex-basis
5.1 flex

flex 屬性,是flex-grow,flex-shrink,felx-basis三個屬性的簡寫:

屬性 預設值 描述
flex-grow 0 定義彈性盒子項的拉伸因子,即子項分配父項剩餘空間的比,預設值為 0
flex-shrink 1 指定了 flex 元素的收縮規則,子項的收縮所佔的份數,預設值為1 [ 當所有子項相加的寬度大於父項的寬度,每個子項減少的多出的父項寬度的 1/n ]
felx-basis auto 指定了 flex 元素在主軸方向上的初始大小,即子項的寬度
如果屬性值為none        則表示 0 0 auto
如果屬性值為1或者auto   則表示 1 1 auto

屬性值可以為1-3個值連用,他們的具體用法請看下面單獨屬性的詳解

5.2 flex-grow

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

我們通過下面的例子來更直觀的認識一下flex-grow

.flex {
  display: flex;
  width: 600px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.flex li:nth-child(1) {
  width: 200px;
  background-color: red;
}
.flex li:nth-child(2) {
  flex-grow: 1;
  width: 50px;
  background-color: blue;
}
.flex li:nth-child(3) {
  flex-grow: 3;
  width: 50px;
  background-color: green;
}

<ul class="flex">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>

結果如下

flex-grow結果

上面的例子中 b,c 兩項都定義了 flex-grow屬性,
flex容器的剩餘空間分成了4份其中 b 佔 1 份,c 佔 3 份,即 1:3,
flex 容器的剩餘空間長度為600-200-50-50=300px
所以最終abc的長度分別為:a: 200px;b: 50+(300*1/4)=125px;c: 50+(300*3/4)=275px
5.3 flex-shrink

flex-shrink 屬性的預設值為1,如果沒有顯示定義該屬性,將會自動按照預設值 1 在所有子項寬度相加之後計算比率來進行空間收縮

這個屬性正好和flex-grow相反,為縮小時所佔的份數,這裡我們可以自己動手寫一下,自己感受一下,我就不再舉例了

5.4 flex-basis

flex-basis 屬性的初始值為auto,設定或檢索彈性盒伸縮基準值,如果所有子元素的基準值之和大於剩餘空間,則會根據每項設定的基準值,按比率伸縮剩餘空間

取值可以為百分比,也可以為具體的數值,如(20%,或者300px)

這裡需要注意的是 ,如果子容器設定了flex-basis屬性,則他自己的width屬性將會失效,這裡可以理解為flex-basis屬性的權重高於width的權重

5.5 order

order 屬性規定了彈性容器中的可伸縮專案在佈局時的順序,元素按照 order 屬性的數值的增序進行佈局,數值小的排在前面,可以為負值,預設值為 0,擁有相同 order 屬性值的元素按照它們在原始碼中出現的順序進行佈局

5.6 align-self

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

該屬性可能取6個值,除了auto,其他都與align-items屬性完全一致。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

文章到這裡就結束了,感謝閱讀。

如果您對我的部落格內容有疑惑或質疑的地方,請在下方評論區留言,或郵件給我,共同學習進步。

郵箱:[email protected]