1. 程式人生 > 其它 >CSS中Flex佈局的學習筆記

CSS中Flex佈局的學習筆記

前言

最近,在學習一些前端知識。在學習的過程中發現會經常使用到Flex佈局,對這個知識點不太熟悉。因此,專門寫一篇文章來記錄一下學習歷程和心得。

本文的內容參考了網上公開的資料,其中主要參考了這兩個網址:CSS Flexible Box Layout Module Level 1A Complete Guide to Flexbox

什麼是Flex佈局

Flex佈局的英文是Flexbox Layout,也可以稱為Flexible Box,翻譯成中文的意思就是彈性盒子,因為聽上去總感覺怪怪的,所以一般我們都很少直接使用中文翻譯。

Flex佈局的目的是希望即使在容器內大小未知或者動態情況下,提供一種更有效的容器內佈局、對齊和空間分配方式。換句話說,也就是Flex佈局賦予了容器具有能夠改變其內部的寬度、高度,甚至是順序等屬性,可以通過使用

控制其內部的填充樣式,或者使用防止其溢位。

傳統的佈局通常使用blockinline來表示縱向佈局和水平佈局。與傳統的佈局相比,Flex佈局是一種與方向無關的佈局,其優點是能夠提供更好的靈活性,同時也能夠支援一些大型的複雜佈局,尤其是在其內部方向改變、大小重置、伸縮等情況。

基礎知識

Flex佈局是一個知識體系,它包括一系列的屬性值。其中這些屬性值中有些需要被宣告在父容器上,有些需要被宣告在子條目上。一個常規的Flex佈局應該宣告是flex和它的direction。網站[1]給出了這樣一張圖來描述它們之間的關係:

容器中的所有子檢視只可能沿著main axismain startmain end

排列,或者是沿著cross axiscross startcross end排列,沒有其他情況。結合上圖,解釋一下它們的含義:

  1. main axis
    主軸是flex佈局中預設的排列方式。但是,可以通過設定flex-direction來改變其排列方式。

  2. main-start | main-end
    預設的主軸排列方式是容器中的子檢視將自main-startmain-end排列。

  3. main size
    所有子檢視中的寬度的總和(包括內外佈局等)就是容器的寬度。所有子檢視中的高度的總和(包括內外佈局等)就是容器的高度。

  4. cross axis
    垂直於主軸的就是橫軸。橫軸始終與主軸保持垂直,其方向決定於主軸的方向。其實我們可以把上圖看成一個羅盤,在預設情況下主軸是自西向東,那麼此時的橫軸就是自北向南。若主軸通過flex-direction

    屬性更改了方向,主軸不再是自西向東,而是變成了自北向南,那麼根據“橫軸始終與主軸保持垂直”,橫軸就變成了自西向東。

  5. cross-start | cross-end
    預設的橫軸排列方式是容器中的子檢視將自cross-startcross-end排列。

  6. cross size
    子檢視的高度或者寬度就是橫軸的大小。

Flex佈局的屬性

Flex佈局的屬性值有的只能在宣告在容器上,有的只能宣告在容器內的子條目上。如下圖,最外面的矩形方框是容器,容器內部的藍色背景色的方塊是子條目。

宣告在容器上的屬性

  • display
    定義一個Flex的容器,容器的條目是inline還是block取決於宣告的值。

    .container {
        display: flex; /* or inline-flex */
    }
    
  • flex-direction
    設定主軸main-axis的方向,目的是設定容器內子條目的排列方向。取值有四種情況,分別是rowrow-reversecolumncolumn-reverse,與圖對應的關係就是:

    .container{
        flex-direction: row | row-reverse | column | column-reverse;
    }
    
    • row(預設): 從左到右
    • row-reverse: 從右到左
    • column: 從上到下
    • column-reverse: 從下到上
  • flex-wrap
    預設情況下,子條目會在一排顯示。如果需要讓其換行,可以通過這個屬性來進行控制。

    .container{
        flex-wrap: nowrap | wrap | wrap-reverse;
    }
    
    • nowrap(預設): 不換行
    • wrap: 換行
    • wrap-reverse: 翻轉換行
  • flex-flow
    這個屬性是flex-directionflex-wrap的組合,比如我們宣告樣式時,會這樣寫:

    .container{
        flex-direction: row;
        flex-wrap: wrap;
    }
    

    而現在,有了flex-flow這個屬性,我們就可以把上面兩行換成一行:

    .container{
        flex-flow: row | wrap;
    }
    
  • justify-content
    定義在主軸上的每排子條目的排列方式。取值有如下幾種情況:

    .container{
        justify-content: flex-start | flex-end | start | end | left | right | center | space-between | space-around | space-evenly;
    }
    
    • flex-start(預設): 沿著flex-direction的方向靠近start對齊。
    • flex-end: 沿著flex-direction的方向靠近end對齊。
    • start: 同flex-start
    • end: 同flex-end
    • left: 左對齊。
    • right: 右對齊。
    • center: 居中對齊。
    • space-between: 第一個子條目左對齊,最後一個右對齊,其餘均分。
    • space-evenly: 除了子條目佔據的空間外,其餘所有空間進行均分。
    • space-around: 在一行中對子條目進行均分,每一個子條目的左右兩邊的邊距相等。看上去好像感覺沒有均分,這是因為第一個和最後一個的邊只佔了一份,而中間的有兩份。就是這樣:
  • align-items
    定義了子條目沿著橫軸across-axis的排列方式。若想直觀看到效果,可以點選這裡

    .container{
        align-items: stretch | flex-start | flex-end | center | baseline;
    }
    
    • stretch(預設):元素被拉伸以適應容器。如果指定側軸大小的屬性值為'auto',則其值會使專案的邊距盒的尺寸儘可能接近所在行的尺寸,但同時會遵照'min/max-width/height'屬性的限制。
    • flex-start:元素位於容器的開頭。
    • flex-end:元素位於容器的結尾。
    • center:元素位於容器的中心。
    • baseline:元素位於容器的基線上。如彈性盒子元素的行內軸與側軸為同一條,則該值與'flex-start'等效。其它情況下,該值將參與基線對齊。
  • align-content
    在彈性容器內的各項沒有佔用交叉軸上所有可用的空間時對齊容器內的各項(垂直)。容器內必須有多行的專案,該屬性才能渲染出效果。

    .container {
      align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end;
    }
    
    • normal(預設值)沒有設定任何值,就按照原始的方式進行排列。
    • flex-start元素位於容器的開頭。
    • flex-end元素位於容器的結尾。
    • center:元素位於容器的中心。
    • space-between元素位於各行之間留有空白的容器內。
    • space-around元素位於各行之前、之間、之後都留有空白的容器內。
    • space-evenly:元素之間的空間左右均分。
    • stretch:元素被拉伸以適應容器。
    • start:同flex-start
    • end:同flex-end

宣告在容器內子條目的屬性

能夠宣告在子條目上的屬性有:orderflex-growflex-shrinkflex-basisflexalign-self這幾個常用的屬性。

  • order
    通常,子條目的順序按照程式碼中的前後順序進行渲染,但是在Flex佈局中可以通過使用order關鍵字來進行子條目的重排。預設值為0,值越小,排序越靠前。值相同,則按照程式碼的先後順序進行排列。

    .item {
        order: 5;
    }
    
  • flex-grow[2]
    grow表示“擴大,增加”的意思,也就是說當父容器的寬度大於子條目的總和時,此時說明父容器不僅能容納所有的子條目,還有空餘的空間。此時,設定了該屬性值的條目就會根據設定的值進行擴充套件。若所有的子條目都設定成了1,那麼表示所有的條目將均分擴充套件容器。該屬性對負值無效。

    .item {
        flex-grow: 1;
    }
    
  • flex-shrink[2]
    shrink表示“收縮”的意思,也就是說當父容器的寬度小於子條目的總和時,此時說父容器無法容納所有的子條目,子條目溢位了父容器。此時,設定該屬性值就會根據設定的值進行收縮。

    .item {
        flex-shrink: 1;
    }
    
  • flex-basic
    設定元素的寬度。若flex-basicwidth一同設定,前者會覆蓋後者。

  • flex
    為了簡化程式碼,使用flex這個屬性來表示flex-growflex-shrinkflex-basis這個三個屬性值,其中flex-shrinkflex-basis是可選的。flex的預設值為none,此時表示flex-grow:0,flex-shrink:1flex-basis:auto

    .item {
        flex: none;
    }
    

    等同於:

    .item {
       flex-grow: 0;
       flex-shrink: 1;
       flex-basis: auto;
    }
    
  • align-self
    父容器通過align-items來控制子條目的位置,若需要子條目自己控制位置,而不受限於align-items,可以通過使用align-self來設定。

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

其值的含義與align-self類似。

參考資料

[1]:A Complete Guide to Flexbox
[2]:桃園三兄弟之:flex-grow、flex-shrink、flex-basis詳解