[万字长文]一文教你彻底搞懂flex布局



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


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL多数据源是指在一个应用程序中同时使用多个不同的MySQL数据库来存储和管理数据的技术。它可以帮助开发人员更灵活地处理各种数据库操作,提高程序的性能和可扩展性。下面是一个完整的MySQL多数据源教程。 一、设置数据库连接信息 1. 在应用程序的配置件中,创建多个数据库连接的配置项。例如,可以为每个数据源创建一个配置项,分别命名为db1、db2等。 2. 在配置项中,设置每个数据源的连接信息,包括数据库地址、用户名、密码等。 二、创建数据源管理器 1. 创建一个数据源管理器类,用于管理多个数据源。该类需要实现数据源的动态切换和获取。 2. 使用Java的线程安全的数据结构,如ConcurrentHashMap来存储数据源信息。将配置件中的数据库连接信息加载到数据结构中。 3. 实现方法来切换不同的数据源,通过传入数据源的名称来切换到对应的数据库。 三、实现数据源切换 1. 在应用程序中,根据业务需求选择需要使用的数据源。可以通过调用数据源管理器的方法来切换数据源。 2. 在DAO层的代码中,根据当前使用的数据源名称,选择对应的数据源进行数据库操作。 四、使用多数据源进行数据库操作 1. 在DAO层的代码中,区分不同的数据源,并将数据库操作的代码包装在对应的数据源中。 2. 在业务层的代码中,调用DAO层的方法来进行数据库操作。不同的数据源会自动切换。 五、处理事务 1. 如果需要在一个事务中操作多个数据源,可以使用分布式事务的方式来处理。 2. 可以使用开源的分布式事务框架,如Atomikos、Bitronix等来实现多数据源的事务管理。 六、监控和维护 1. 使用监控工具来监控多个数据源的使用情况,包括连接数、查询次数等。 2. 定期对数据库进行维护,包括索引优化、数据清理等工作,以保证数据库的性能和稳定性。 通过以上步骤,我们可以实现MySQL多数据源的配置和使用。使用多数据源可以更好地管理和处理不同的数据库操作,在提高程序性能和可扩展性的同时,也提供了更灵活的数据操作方式。同时,需要注意合理选择和配置数据源,以及监控和维护数据库,以保证系统的运行效率和数据的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值