[萬字長文]一文教你徹底搞懂flex佈局

梓川禰豆子發表於2020-12-09



Flex佈局是什麼?

佈局的傳統解決方案,基於盒狀模型,依賴 display屬性 + position屬性 + float屬性。它對於那些特殊佈局非常不方便,比如,垂直居中就不容易實現。

Flex是Flexible Box的縮寫,意為”彈性佈局”,用來為盒狀模型提供最大的靈活性。

彈性盒子是 CSS3 的一種新的佈局模式。

CSS3 彈性盒( Flexible Box 或 flexbox),是一種當頁面需要適應不同的螢幕大小以及裝置型別時確保元
素擁有恰當的行為的佈局方式。

引入彈性盒佈局模型的目的是提供一種更加有效的方式來對一個容器中的子元素進行排列、對齊和分配空白
空間。

任何一個容器都可以指定為Flex佈局。

.box{
  display: flex;
}

行內元素也可以使用Flex佈局。

.box{
  display: inline-flex;
}

Webkit核心的瀏覽器,必須加上-webkit字首。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

注意,設為Flex佈局以後,子元素的float、clear和vertical-align屬性將失效。



彈性容器常用的屬性:flex-direction、justify-content 、align-items、flex-grow和flex。

img





Flex 的原理

首先,Flex 佈局支援橫向和縱向,可以做一個抽象,把 Flex 延伸的方向稱為“主軸”,把跟它垂直的方向稱為“交叉軸”。這樣,flex 項中的 widthheight 就會稱為交叉軸尺寸或者主軸尺寸。

而 Flex 又支援反向排布,這樣,我們又需要抽象出交叉軸起點、交叉軸終點、主軸起點、主軸終點,它們可能是 topleftbottomright

Flex 佈局中有一種特殊的情況,那就是 flex 容器沒有被指定主軸尺寸,這個時候,實際上 Flex 屬性完全沒有用了,所有 Flex 尺寸都可以被當做 0 來處理,Flex 容器的主軸尺寸等於其它所有 flex 項主軸尺寸之和。

Flex 排版

Flex 排版三個步驟:分行、計算主軸、計算交叉軸

第一步把 flex 項分行,有 flex 屬性的 flex 項可以暫且認為主軸尺寸為 0,所以,它可以一定放進當前行。

接下來,把 flex 項逐個放入行,不允許換行的話,就“無腦地”把 flex 項放進同一行。

允許換行的話,我們就先設定主軸剩餘空間為 Flex 容器主軸尺寸,每放入一個就把主軸剩餘空間減掉它的主軸尺寸,直到某個 flex 項放不進去為止,換下一行,重複前面動作。

分行過程中,我們會順便對每一行計算兩個屬性:交叉軸尺寸和主軸剩餘空間,交叉軸尺寸是本行所有交叉軸尺寸的最大值,而主軸剩餘空間前面已經說過。




第二步計算每個 flex 項主軸尺寸和位置。

如果 Flex 容器是不允許換行的,並且最後主軸尺寸超出了 Flex 容器,就要做等比縮放。

如果 Flex 容器有多行,那麼根據我們前面的分行演算法,必然有主軸剩餘空間,這時候,我們要找出本行所有的帶 Flex 屬性的 flex 項,把剩餘空間按 Flex 比例分給它們即可。

之後,就可以根據主軸排布方向,確定每個 flex 項的主軸位置座標了。

如果本行完全沒有帶 flex 屬性的 flex 項justify-content 機制就要生效了,它有幾個不同的值會影響剩餘空白如何分配,作為實現者,我們只要在計算 flex 項座標的時候,加上一個數值即可。

例如,如果 justify-content 是 flex-start 就要加到第一個 flex 項身上,如果是 center 就給第一個 flex 項加一半的尺寸,如果是 space-between,就要給除了第一個以外的每個 flex 項加上“(flex 項數減一)分之一”。




第三步計算 flex 項的交叉軸尺寸和位置。

交叉軸的計算首先是根據 align-content 計算每一行的位置,這部分跟 justify-content 非常類似。

再根據 alignItems 和 flex 項的 alignSelf 來確定每個元素在行內的位置。

計算完主軸和交叉軸,每個 flex 項的座標、尺寸就都確定了,這樣就完成了整個的 Flex 佈局。

總而言之,justify控制的主要是主軸,align控制的是交叉軸。

例如,flex-direction(主軸方向)為水平(預設)時,justify控制水平方向的佈局,align控制的是垂直方向的佈局。

而相反的,flex-direction為垂直時,justify控制垂直方向上的佈局,align控制的是水平方向的佈局。

容器屬性

主要使用的屬性主要有以下幾個。

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

其中最常用的就是justify-content和align-items了。

flex-wrap(使用頻率:高)

讓彈性盒元素在必要的時候拆行。

img

簡單示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        main {
            display: flex;
            border: 2px solid black;
            width: 1000px;
        }

        .item {
            width: 200px;
            height: 200px;
            background-color: coral;
            margin-right: 10px;
            margin-bottom: 10px;
        }
        .test{
            margin-top: 20px;
            width: 200px;
            height: 200px;
            border: 2px solid black;
        }
    </style>
</head>
<body>
<main>
    <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>
</main>

<div class="test">
    <p>這是正常的200px</p>
</div>

</body>
</html>




img



使用了flex-wrap:wrap後。

main {

    display: flex;
    /*換行*/
    flex-wrap: wrap;

    border: 2px solid black;
    width: 1000px;
}

img

使用了flex-wrap: wrap-reverse;後。

main {

    display: flex;
    flex-wrap: wrap-reverse;

    border: 2px solid black;
    width: 1000px;
}

img


flex-direction(使用頻率:高)


flex-direction 指定了彈性子元素在父容器中的位置。此屬性作用於父容器。


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


引數:
row :橫向從左到右排列(左對齊),預設的排列方式。
row-reverse :反轉橫向排列(右對齊,從後往前排,最後一項排在最前面。
column :縱向排列。
column-reverse :反轉縱向排列,從後往前排,最後一項排在最上面。

img

img



flex-flow(flex-direction + flex-wrap的簡寫形式)

flex-flow 屬性是 flex-direction 和 flex-wrap 屬性的複合屬性。

flex-flow 屬性用於設定或檢索彈性盒模型物件的子元素排列方式。

flex-direction 屬性規定靈活專案的方向。

flex-wrap 屬性規定靈活專案是否拆行或拆列。

img




justify-content(使用頻率:非常高)


justify-content屬性應用在彈性容器上,把彈性項沿著彈性容器的主軸線(main axis)對齊。此屬性作用於
父容器。

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

img




引數:

  • flex-start :彈性專案向行頭緊挨著填充。這個是預設值。第一個彈性項的main-start外邊距邊線被放置在
    該行的main-start邊線,而後續彈性項依次平齊擺放。預設屬性值為flex-start。
  • flex-end :彈性專案向行尾緊挨著填充。第一個彈性項的main-end外邊距邊線被放置在該行的main-end邊
    線,而後續彈性項依次平齊擺放。
  • center :彈性專案居中緊挨著填充。(如果剩餘的自由空間是負的,則彈性專案將在兩個方向上同時溢
    出)。
  • space-between :彈性專案平均分佈在該行上。如果剩餘空間為負或者只有一個彈性項,則該值等同於flex-start。否則,第1個彈性項的外邊距和行的main-start邊線對齊,而最後1個彈性項的外邊距和行的main-end邊線對齊,然後剩餘的彈性項分佈在該行上,相鄰專案的間隔相等。
  • space-around :彈性專案平均分佈在該行上,兩邊留有一半的間隔空間。如果剩餘空間為負或者只有一個彈性項,則該值等同於center。否則,彈性專案沿該行分佈,且彼此間隔相等(比如是20px),同時首尾兩邊和彈性容器之間留有一半的間隔(1/2*20px=10px)。



描述測試
flex-start預設值。專案位於容器的開頭。測試
flex-end專案位於容器的結尾。測試
center專案位於容器的中心。測試
space-between專案位於各行之間留有空白的容器內。測試
space-around專案位於各行之前、之間、之後都留有空白的容器內。測試
initial設定該屬性為它的預設值。測試
inherit從父元素繼承該屬性。

justify-items(使用頻率:低)

CSSjustify-items 屬性為所有盒中的專案定義了預設的 justify-self , 可以使這些專案以預設方式沿適當軸線對齊到每個盒子。

主要語法:

/* Positional alignment */
justify-items: center;     /* Pack items around the center */
justify-items: start;      /* Pack items from the start */
justify-items: end;        /* Pack items from the end */
justify-items: flex-start; /* Pack flex items from the start */
justify-items: flex-end;   /* Pack flex items from the end */
justify-items: self-start;
justify-items: self-end;
justify-items: left;       /* Pack items from the left */
justify-items: right;      /* Pack items from the right */

詳情文件:https://developer.mozilla.org/zh-CN/docs/Web/CSS/justify-items

img



align-items(使用頻率:非常高)

align-items 設定或檢索彈性盒子元素在側軸(縱軸)方向上的對齊方式。此屬性作用於父容器。



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


引數:

  • flex-start :彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸起始邊界。預設屬性值為flex-start。

  • flex-end :彈性盒子元素的側軸(縱軸)起始位置的邊界緊靠住該行的側軸結束邊界。

  • center :彈性盒子元素在該行的側軸(縱軸)上居中放置。(如果該行的尺寸小於彈性盒子元素的尺寸,則
    會向兩個方向溢位相同的長度)。

  • baseline :如彈性盒子元素的行內軸與側軸為同一條,則該值與’flex-start’等效。其它情況下,該值將參與
    基線對齊

  • stretch :如果指定側軸大小的屬性值為auto,則其值會使專案的邊距盒的尺寸儘可能接近所在行的尺寸,
    但同時會遵照min/max-width/height屬性的限制。

img



示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        main {

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


            border: 2px solid black;
            height: 500px;
            width: 1000px;
        }

        .item {
            width: 200px;
            height: 100px;
            background-color: coral;
            border: 2px solid black;
            margin: 10px;

        }

        .test {
            margin: 10px;
            width: 200px;
            height: 200px;
            border: 2px solid black;
        }
    </style>
</head>
<body>
<main>
    <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>
</main>

<div class="test">
    <p>這是正常的200px</p>
</div>

</body>
</html>

img





align-content(使用頻率:低)

align-content 屬性在彈性容器內的各項沒有佔用交叉軸上所有可用的空間時,對齊容器內的各項(垂直)。


**提示:**使用 justify-content 屬性對齊主軸上的各項(水平)。


**注意:**容器內必須有多行的專案,該屬性才能渲染出效果。



img

想親自除錯各個屬性的效果,可進入菜鳥教程嘗試一番。點選這裡進入。

img

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        main {

            display: flex;
            flex-wrap: wrap;
            
            /*核心*/
            align-content: center;

            border: 2px solid black;
            height: 800px;
            width: 1000px;
        }

        .item {
            width: 200px;
            height: 100px;
            background-color: coral;
            border: 2px solid black;
            margin: 10px;

        }

        .test {
            margin: 10px;
            width: 200px;
            height: 200px;
            border: 2px solid black;
        }
    </style>
</head>
<body>
<main>
    <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>
</main>

<div class="test">
    <p>這是正常的200px</p>
</div>

</body>
</html>

img

專案屬性

order(使用頻率:中)

img

flex-grow(使用頻率:中)

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

語法: flex-grow: <number>

如果所有專案的flex-grow屬性都為1,則它們將等分剩餘空間(如果有的話)。如果一個專案的flex-grow屬性
為2,其他專案都為1,則前者佔據的剩餘空間將比其他項多一倍。

img

flex-shrink(使用頻率:中)

img

flex-basis(使用頻率:中)

img

  • 如果width也沒有設定,flex-basis = content的寬度。

  • 可以是長度單位,也可以是百分比,百分比是按照父元素的width為標準。

  • 預設值為 0,不是 auto,如果取值為 auto 的話,它的值就等於 flex-items的 width(或者預設的大小,width沒有設定的話)。

  • 使用方法:配合 flex-wrap 一起使用,如果 flex-wrap 的值為 nowrap 的話,flex-basis 的作用不大,
    相反,如果 flex-wrap 的值為 wrap 的話,flex容器根據 flex-basis 計算是否需要換行。









flex(重中之重,使用頻率:極高)

是**(flex-grow,flex-shrink,flex-basis)**的簡寫形式

flex 屬性用於指定彈性子元素如何分配空間。

語法:flex: auto | initial | none | inherit | [ flex-grow ] || [ flex-shrink ] || [ flex-basis ]

引數:

  • auto : 計算值為 1 1 auto。
  • initial : 計算值為 0 1 auto。
  • none :計算值為 0 0 auto。
  • inherit :從父元素繼承。
  • [ flex-grow ] :定義彈性盒子元素的擴充套件比率。
  • [ flex-shrink ] :定義彈性盒子元素的收縮比率。
  • [ flex-basis ] :定義彈性盒子元素的預設基準值。

如何理解這三個值放在一起的意義呢?

  • flex-basis

    basis英文意思是<主要成分、基準>,可以理解為它設定了當前flex-item在主軸上的基準長度。所以它和width(水平方向為主軸時)放在一起時, 瀏覽器會優先使用flex-basis。

    同時,flex-grow與flex-shrink也將會在該基準上,對元素在主軸上的長度進行放大和縮小,計算公式稍稍有些繞腦。

  • flex-grow

    grow英文意思是<擴大,擴充套件,增加>,這就代表當父元素的寬度大於子元素寬度之和時,並且父元素有剩餘,這時,flex-grow就會說我要成長,我要長大,怎麼樣才能成長呢,當然是分享父元素的空間了。

    該屬性用來設定當父元素的寬度大於所有子元素的寬度的和時(即父元素會有剩餘空間),子元素如何分配父元素的剩餘空間。 flex-grow的預設值為0,意思是該元素不索取父元素的剩餘空間,如果值大於0,表示索取。值越大,索取的越厲害。

    舉個例子: 父元素寬400px,有兩個子元素:A和B。A寬為100px,B寬為200px。 則空餘空間為 400-(100+200)= 100px。 如果A,B都不索取剩餘空間,則有100px的空餘空間。

    如果A索取剩餘空間:設定flex-grow為1,B不索取。則最終A的大小為 自身寬度(100px)+ 剩餘空間的寬度(100px)= 200px 。

    如果A,B都設索取剩餘空間,A設定flex-grow為1,B設定flex-grow為2。則最終A的大小為 自身寬度(100px)+ A獲得的剩餘空間的寬度(100px (1/(1+2))),最終B的大小為 自身寬度(200px)+ B獲得的剩餘空間的寬度(100px (2/(1+2)))



  • flex-shrink

    shrink英文意思是<收縮>,這就代表當父元素的寬度小於子元素寬度之和時,並且超出了父元素的寬度,這時,flex-shrink就會說外面的世界太苦了,我還是回到父親的懷抱中去吧!因此,flex-shrink就會按照一定的比例進行收縮。

    該屬性用來設定當父元素的寬度小於所有子元素的寬度的和時(即子元素會超出父元素),子元素如何縮小自己的寬度的。

    flex-shrink的預設值為1,當父元素的寬度小於所有子元素的寬度的和時,子元素的寬度會減小。值越大,減小的越厲害。如果值為0,表示不減小。

    舉個例子: 父元素寬400px,有兩子元素:A和B。A寬為200px,B寬為300px。 則A,B總共超出父元素的寬度為(200+300)- 400 = 100px。 如果A,B都不減小寬度,即都設定flex-shrink為0,則會有100px的寬度超出父元素。

    如果A不減小寬度:設定flex-shrink為0,B減小。則最終B的大小為 自身寬度(300px) - 總共超出父元素的寬度(100px)= 200px。

    如果A,B都減小寬度,A設定flex-shirk為3,B設定flex-shirk為2。此時會出現一個抽象的長度,等於(A的長度 * A的flex-shirk + B的長度 * B的flex-shirk),A和B最終縮小長度的佔比為(A的長度 * A的flex-shirk)/(B的長度 * B的flex-shirk)

    按照這個計算規則,A和B的比例為:(200px3/(2003 + 3002)比(200px3/(2003 + 3002),即1比1.

    所以它們會等比地平分100px中縮小的長度,即各自縮小50px。

    則最終A的大小為 自身寬度(200px)- A減小的寬度(100px * (200px * 3/(200 * 3 + 300 * 2))) = 150px,最終B的大小為 自身寬度(300px)- B減小的寬度(100px * (300px * 2/(200 * 3 + 300 * 2))) = 250px

tips:當父盒子有padding時,上述flex-grow和flex-padding的計算結果似乎會出現一些偏差,所以在使用flex屬性時,父盒子的左右padding最好設定成0。具體偏差是如何造成的,還需多加研究。

flex縮寫規則

  • flex 取值為 none,則計算值為 0 0 auto,如下是等同的:
.item {flex: none;}
.item {
    flex-grow: 0;
    flex-shrink: 0;
    flex-basis: auto;
}
  • flex取值為 auto,計算值為 1 1 auto,如下是等同的:
.item {flex: auto;}
.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: auto;
}
  • 當 flex 取值為一個非負數字,則該數字為 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%。
如下是等同的
.item {flex: 1;}
.item {flex-grow: 1; flex-shrink: 1; flex-basis: 0%;}
  • 當 flex 取值為一個長度或百分比,則視為 flex-basis 值,flex-grow 取 1,flex-shrink取 1,有如下等同情況(注意 0% 是一個百分比而不是一個非負數字):
.item-1 {flex: 0%;}
.item-1 { flex-grow: 1; flex-shrink: 1; flex-basis: 0%;}

.item-2 {flex: 24px;} 
.item-2 { flex-grow: 1; flex-shrink: 1; flex-basis: 24px;}
  • 當 flex取值為兩個非負數字,則分別視為 flex-grow和 flex-shrink的值,flex-basis取 0%,如下是等同的:
.item {flex: 2 3;} 
.item { flex-grow: 2; flex-shrink: 3; flex-basis: 0%;} 

  • 當 flex取值為一個非負數字和一個長度或百分比,則分別視為 flex-grow和 flex-basis的值,flex-shrink取 1,如下是等同的:
 .item {flex: 20 30px;}
 .item { flex-grow: 20; flex-shrink: 1; flex-basis: 30px;} 




align-self(使用頻率:中)

就是讓該item不遵循父元素中align-items的定義,而是設定成自己的,起到鶴立雞群的效果。

主要語法: align-self: flex-start | flex-end | center | baseline | stretch

居中對齊彈性物件元素內的某個項:

img




justify-self(使用頻率:低)

這個使用應該不多,主要是專門用來指定該flex-item的對齊方式,覆蓋父盒子中justify-items的設定,可以起到鶴立雞群的作用。

詳情:這裡

主要語法

/* 位置對齊 */
justify-self: center;     /* 在中間放置元素 */
justify-self: start;      /* 在開始處放置元素 */
justify-self: end;        /* 在結束處防止元素 */
justify-self: flex-start; /* 與 'start' 等效。注意 justify-self 在 Flexbox 佈局中被忽略。 */
justify-self: flex-end;   /* 與 'end' 等效。注意 justify-self 在 Flexbox 佈局中被忽略。 */
justify-self: self-start;
justify-self: self-end;
justify-self: left;       /* 在左側放置元素 */
justify-self: right;      /* 在右側放置元素 */

img

常見面試題

垂直居中

img



<div class="main">
    <div class="box">未知高度上下左右居中</div>
</div>

css部分

.main{
    display: flex;
    height: 400px;
    justify-content: center;
    align-items: center;
    border: 1px solid black;
}

.box{
    width: 300px;
    border: 1px solid black;
}





按比例分佈

img

<div class="box">
    <div id="id1">1</div>
    <div id="id2">2</div>
    <div id="id3">3</div>
</div>

css部分

.box {
    width: 50%;
    margin: 50px auto;
    display: flex;
}

.box div {

    border: 1px solid red;
}

#id1 {
    flex: 1;
}

#id2 {
    flex: 2;
}

#id3 {
    flex: 3;
}




兩欄佈局

左固定,右自適應

img

html部分

<div class="main">
    <div class="left">固定寬度300px</div>
    <div class="right">自適應寬度</div>
</div>

css部分

.main {
    display: flex;
}

.left,
.right {
    height: 300px;
    border: 1px solid red;
    box-sizing: border-box;
}

.left{
    width: 300px;
}

.right{
    width: 100%;
}




左自適應,右固定

img

<div class="main">
    <div class="left">自適應寬度</div>
    <div class="right">固定寬度300px</div>
</div>

css部分

.main {
    display: flex;
}
.left,
.right {
    height: 300px;
    border: 1px solid red;
    box-sizing: border-box;
}

.left{
    width: 100%;
}

.right{
    width: 300px;
}


三欄佈局




左右固定,中間自適應

img




中間固定,左右自適應

img

<div class="box">
    <div class="left">自適應</div>
    <div class="center">固定寬度</div>
    <div class="right">自適應</div>
</div>

css部分

.box {
    margin: 50px auto;
    display: flex;
}

.box div {
    border: 1px solid black;
    height: 500px;
}

.left {
    flex: 1;
}

.center {
    flex: 300px;
}

.right {
    /*是左邊的兩倍寬*/
    flex: 2;
}

總結:主要抓住flex這個屬性,確定好flex-grow、flex-shrink、flex-basis這三個屬性就ok了。

階梯佈局

html部分

<div class="container">
      
    <div class="item1">元素1</div>
      
    <div class="item2">元素2</div>
      
    <div class="item3">元素3</div>
</div>

css部分

*{
    padding: 0;
    border: 0;
}
.container{
    display: flex;
    flex-direction: column;
    border: 1px solid black;
    height: 500px;
}

.container div{
    width: 200px;
    height: 50px;
}

.item1{
    background-color: red;
}

.item2{
    background-color: green;
}

.item3{
    background-color: yellow;
}

剛開始,設定垂直方向為主軸,然後元素排列如下。

img

接下來,使用align-self來設定每一個元素在交叉軸的位置,flex-start/center/flex-start,效果如下。

img

斜對稱

html部分

<div class="box">
    <div class="left-top"></div>
    <div class="right-bottom"></div>
</div>

css部分

.box {

    height: 500px;
    border: 1px solid black;
    width: 50%;
    margin: 20px auto 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

.box div {
    width: 100px;
    height: 100px;
    background-color: red;
    border: 1px solid black;

}

.left-top{

}

.right-bottom{
    align-self: flex-end;
}

img

.box {
    height: 500px;
    border: 1px solid black;
    width: 50%;
    margin: 20px auto 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

.box div {
    width: 100px;
    height: 100px;
    background-color: red;
    border: 1px solid black;
}


.left-bottom{
    align-self: flex-end;
}

.right-top{

}

img




瀑布流

img

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        /* css樣式 */
        body {
            background: #e5e5e5;
        }

        /* 瀑布流最外層 */
        #root {
            display: flex;
            flex-direction: row;
            margin: 0 auto;
            width: 1200px;
        }

        .itemContainer {
            display: flex;
            margin-right: 10px;
            flex-direction: column;
            width: 240px;
        }

        /* 每一列圖片包含層 */
        .item {
            margin-bottom: 10px;
            background: #fff;
            border: 2px solid black;
        }

        .item:hover {
            box-shadow: 2px 2px 2px rgba(0, 0, 0, .5);
        }

        /* 圖片 */
        .itemImg {
            width: 100%;
        }

        /* 圖片下的資訊包含層 */
        .userInfo {
            padding: 5px 10px;
        }


        .username {
            margin-left: 5px;
            text-shadow: 2px 2px 2px rgba(0, 0, 0, .3);
        }
    </style>
</head>
<body>
<div id="root">
    <div class="itemContainer">
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper01.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper02.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper03.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper04.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper05.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper06.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper07.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper08.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper09.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper10.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper11.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper12.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper13.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper14.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper15.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper16.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>

    </div>
    <div class="itemContainer">


        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper14.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper15.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper16.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper01.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper02.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper03.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper04.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper05.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper06.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper07.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper08.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper09.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper10.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper11.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper12.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper13.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
    </div>
    <div class="itemContainer">

        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper09.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper10.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper11.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper12.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper13.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper14.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper15.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper16.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper01.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper02.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper03.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper04.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper05.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper06.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper07.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
        <div class="item">
            <img class="itemImg" src="http://qinniu.douziqianduan.icu/wallpaper08.jpg" alt=""/>
            <div class="userInfo">
                <span class="username">牽起你的左手護著你</span>
            </div>
        </div>
    </div>

</div>
</body>
</html>

實踐後發現,純css實現的瀑布流只能是一列一列的排布,所以還是得用js來實現瀑布流更符合我們常見的瀑布流



總結

flex佈局就是為了彈性盒子在水平和垂直方向上更好地排列而誕生的解決方案。

參考

https://www.bilibili.com/video/BV1t7411E7tn?from=search&seid=12765307109649912847

http://www.woc12138.com/article/34

Flex 佈局教程:語法篇

https://segmentfault.com/a/1190000016255824


相關文章