css弹性布局-flex布局

本文介绍CSS3新增的布局方式,flex弹性布局,便于页面布局及项目。

传统的css布局

我们知道传统的css定位比较麻烦,比如垂直居中,比较难实现,但是问题比较多,很难实现自适应。

居中

代码:

// html代码
<div class="oldcenter">
    <div class="oldcenter-div">居中</div>
</div>
// css代码
.oldcenter{
    border: 1px solid #D53419;
    background-color: #50E9EE;
    width: 250px;
    height: 250px;
    position: relative;
}
.oldcenter-div {
    width: 50px;
    height: 50px;
    background-color: #DF6A41;
    margin: 0 auto;            //左右居中
    margin-top: 50%;        //外边框距离父元素高度顶部框线50%
    bottom: 25px;            //上移自身高度的一半 50/2 = 25px
    position: relative;        //设置为相对父元素定位
}

上面的代码可以实现居中,原理是先让子div向下移动其父元素50%的高度,再向上移动自身高度50px的一半,即25px;实现了垂直居中。代码非常冗余。

而且,如果是动态添加的列表元素,居中更麻烦

  • 列表1
  • 列表2
  • 列表3
  • 列表4
  • 列表5

代码:

// html代码
<div class="oldcenter">
    <ul class="old-ul">
        <li>列表1</li>
        <li>列表2</li>
        <li>列表3</li>
        <li>列表4</li>
        <li>列表5</li>
    </ul>
</div>
// css代码
.oldcenter{
    border: 1px solid #D53419;
    background-color: #50E9EE;
    width: 250px;
    height: 250px;
    position: relative;
}
.old-ul{
    margin-top: 0px;
    height: 250px;
}
.old-ul>li{
    height: 50px;
    line-height: 50px;
}

这个列表样式看似简单,但是如果列表中的内容是动态添加的呢?我们应该怎样设置每一个列表项的高度和行高?不可能每添加一次就改一次css代码,是不是非常的不方便。

传统的布局需要依赖于display,position,float等属性,样式调起来很不容易,所以需要改进。

flex布局

2009年,W3C组织提出了一种新的布局方式–弹性布局,即flex布局。这种布局用少量、简单的代码,可以实现页面的响应式布局。并且如今已经得到除IE9-以外的所有浏览器的支持,完全不影响使用。

初识flex

我们先来认识一下flex,看看实现传统布局中的垂直居中是否方便。


flex居中

代码:

// html代码
<div class="newcenter">
    <div class="newcenter-div">flex居中</div>
</div>
// css代码
.newcenter{
    width: 250px;
    height: 250px;
    border: 1px solid #D53419;
    background-color: #50E9EE;
    display: flex;            //声明为flex布局
    justify-content: center;//水平方向左右居中
    align-items: center;    //垂直方向上下居中
}
.newcenter-div{
    width: 50px;
    height: 50px;
    background-color: #DF6A41;
}

是不是觉得简单易懂,而且用起来也比较方便。

flex基本概念

将元素的display属性设置为flex后,该元素就成为了”flex容器”,之后的操作类似于在容器中操作,它的子元素都是容器中的部分。

flex容器属性

flex容器有6个属性

为了减少重复代码,且方便读者看懂,该标题(flex容器属性)下的所有代码的css均基于以下两个class属性

.parent-container{
    width: 400px;
    height: 300px;
    border: 1px solid #D53419;
    background-color: #50E9EE;
}
.parent-container>p{
    width: 50px;
    height: 30px;
    border: 1px solid #2548E7;
    background-color: #dbc21d;
    margin: 5px;
}

flex-direction

该属性用来定义,子元素的排列方向.

序号 属性值 含义
1 row 水平方向,从左往右依次排列(默认值)
2 row-reverse 水平方向,从右往左依次排列
3 column 垂直方向,从上往下依次排列
4 column-reverse 垂直方向,从下往上依次排列

1.row

flex1

flex2

flex3

flex4

flex5

flex6

flex7

代码:

// html代码
<div class="parent-container container-row">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
</div>
// css代码
.container-row{
    display: flex;
    flex-direction: row;
}

2.row-reverse

flex1

flex2

flex3

flex4

flex5

flex6

flex7

代码:

// html代码
<div class="parent-container container-rowreverse">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
</div>
// css代码
.container-rowreverse{
    display: flex;
    flex-direction: row-reverse;
}

3.column

flex1

flex2

flex3

flex4

flex5

flex6

flex7

代码:

// html代码
<div class="parent-container container-column">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
</div>
// css代码
.container-column{
    display: flex;
    flex-direction: column;
}

4.column-reverse

flex1

flex2

flex3

flex4

flex5

flex6

flex7

代码:

// html代码
<div class="parent-container container-columnreverse">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
</div>
// css代码
.container-columnreverse{
    display: flex;
    flex-direction: column-reverse;
}

flex-wrap

该属性用来定义,如果子元素一排排不下,那么它的换行情况.

序号 属性值 含义
1 nowrap 表示不换行(默认值)
2 wrap 换行
3 wrap-reverse 换行,并且反向排列

1.nowrap

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

代码:

// html代码
<div class="parent-container container-nowrap">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
    <p>flex8</p>
    <p>flex9</p>
    <p>flex10</p>
    <p>flex11</p>
</div>
// css代码
.container-nowrap{
    display: flex;
    flex-wrap: nowrap;
}

2.wrap

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

代码:

// html代码
<div class="parent-container container-wrap">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
    <p>flex8</p>
    <p>flex9</p>
    <p>flex10</p>
    <p>flex11</p>
</div>
// css代码
.container-wrap{
    display: flex;
    flex-wrap: wrap;
}

3.wrap-reverse

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

代码:

// html代码
<div class="parent-container container-wrapreverse">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
    <p>flex5</p>
    <p>flex6</p>
    <p>flex7</p>
    <p>flex8</p>
    <p>flex9</p>
    <p>flex10</p>
    <p>flex11</p>
</div>
// css代码
.container-wrapreverse{
    display: flex;
    flex-wrap: wrap-reverse;
}

flex-flow

该属性是flex-direction属性和flex-wrap属性的结合,即flex-direction属性和flex-wrap属性的简写形式,这里就不再说明.

.container{
    flex-flow: flex-direction || flex-wrap;
}

justify-content

该属性用来定义,元素在水平方向上的对齐方式.

序号 属性值 含义
1 flex-start 靠左对齐(默认值)
2 flex-end 靠右对齐
3 center 水平居中对齐
4 space-between 两端对齐,子元素之间间隔相等,两端无间隔
5 space-around 平均对齐,子元素两侧间隔相等,且不重叠

1.flex-start

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-justify-flexstart">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
</div>
// css代码
.container-justify-flexstart{
    display: flex;
    justify-content: flex-start;
}

2.flex-end

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-justify-flexend">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
</div>
// css代码
.container-justify-flexend{
    display: flex;
    justify-content: flex-end;
}

3.center

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-justify-center">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
</div>
// css代码
.container-justify-center{
    display: flex;
    justify-content: center;
}

4.space-between

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-justify-spacebetween">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
</div>
// css代码
.container-justify-spacebetween{
    display: flex;
    justify-content: space-between;
}

5.space-around

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-justify-spacearound">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    <p>flex4</p>
</div>
// css代码
.container-justify-spacearound{
    display: flex;
    justify-content: space-around;
}

align-items

该属性用来定义,元素在垂直方向上的对齐方式.

序号 属性值 含义
1 flex-start 顶部对齐(默认值)
2 flex-end 底部对齐
3 center 垂直居中对齐
4 baseline 子元素第一行文字的基线对齐
5 stretch 占满父元素整个垂直方向的高度,即高度与父元素相同(项目未设置高度或设为auto的情况下生效)(默认值)

1.flex-start

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-aItems-flexstart">
    <p style="height: 80px">flex1</p>
    <p style="height: 40px">flex2</p>
    <p style="height: 120px">flex3</p>
    <p style="height: 100px">flex4</p>
</div>
// css代码
.container-aItems-flexstart{
    display: flex;
    align-items: flex-start;
}

2.flex-end

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-aItems-flexend">
    <p style="height: 80px">flex1</p>
    <p style="height: 40px">flex2</p>
    <p style="height: 120px">flex3</p>
    <p style="height: 100px">flex4</p>
</div>
// css代码
.container-aItems-flexend{
    display: flex;
    align-items: flex-end;
}

3.center

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-aItems-center">
    <p style="height: 80px">flex1</p>
    <p style="height: 40px">flex2</p>
    <p style="height: 120px">flex3</p>
    <p style="height: 100px">flex4</p>
</div>
// css代码
.container-aItems-center{
    display: flex;
    align-items: center;
}

4.baseline

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-aItems-baseline">
    <p style="height: 80px;font-size: 20px">flex1</p>
    <p style="height: 40px;font-size: 14px">flex2</p>
    <p style="height: 120px;font-size: 22px">flex3</p>
    <p style="height: 100px;font-size: 25px">flex4</p>
</div>
// css代码
.container-aItems-baseline{
    display: flex;
    align-items: baseline;
}

5.stretch

flex1

flex2

flex3

flex4

代码:

// html代码
<div class="parent-container container-aItems-stretch">
    <p style="height: initial;">flex1</p>
    <p style="height: initial;">flex2</p>
    <p style="height: 50px;">flex3</p>
    <p style="height: 150px;">flex4</p>
</div>
// css代码
.container-aItems-stretch{
    display: flex;
    align-items: stretch;
}

align-content

该属性用来定义,多排子元素在垂直方向上每一排之间的对齐方式.

该属性必须在具有多排子元素的父元素中才能生效,即必须有 flex-wrap: wrap; 或 flex-wrap: wrap-reverse;且父元素中有多个子元素,一排放不下的情况下才有效果.

序号 属性值 含义
1 flex-start 垂直方向上,排之间靠近顶部对齐
2 flex-end 垂直方向上,排之间靠近底部对齐
3 center 垂直方向上,排之间居中对齐
4 space-between 垂直方向上,第一排与最后一排上下两端紧靠父元素,排之间的间隔平分
5 space-around 垂直方向上平均对齐,排之间两侧间隔相等,且不重叠
6 stretch 所有排占满父元素整个垂直方向的高度(默认值)

1.flex-start

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

flex12

flex13

flex14

flex15

flex16

flex17

flex18

flex19

flex20

flex21

flex22

flex23

flex24

flex25

代码:

// html代码
<div class="parent-container container-aContent-flexstart">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    ···            //多个p元素
    <p>flex23</p>
    <p>flex24</p>
    <p>flex25</p>
</div>
// css代码
.container-aContent-flexstart{
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
}

2.flex-end

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

flex12

flex13

flex14

flex15

flex16

flex17

flex18

flex19

flex20

flex21

flex22

flex23

flex24

flex25

代码:

// html代码
<div class="parent-container container-aContent-flexend">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    ···            //多个p元素
    <p>flex23</p>
    <p>flex24</p>
    <p>flex25</p>
</div>
// css代码
.container-aContent-flexend{
    display: flex;
    flex-wrap: wrap;
    align-content: flex-end;
}

3.center

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

flex12

flex13

flex14

flex15

flex16

flex17

flex18

flex19

flex20

flex21

flex22

flex23

flex24

flex25

代码:

// html代码
<div class="parent-container container-aContent-center">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    ···            //多个p元素
    <p>flex23</p>
    <p>flex24</p>
    <p>flex25</p>
</div>
// css代码
.container-aContent-center{
    display: flex;
    flex-wrap: wrap;
    align-content: center;
}

4.space-between

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

flex12

flex13

flex14

flex15

flex16

flex17

flex18

flex19

flex20

flex21

flex22

flex23

flex24

flex25

代码:

// html代码
<div class="parent-container container-aContent-spacebetween">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    ···            //多个p元素
    <p>flex23</p>
    <p>flex24</p>
    <p>flex25</p>
</div>
// css代码
.container-aContent-spacebetween{
    display: flex;
    flex-wrap: wrap;
    align-content: space-between;
}

5.space-around

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

flex12

flex13

flex14

flex15

flex16

flex17

flex18

flex19

flex20

flex21

flex22

flex23

flex24

flex25

代码:

// html代码
<div class="parent-container container-aContent-spacearound">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    ···            //多个p元素
    <p>flex23</p>
    <p>flex24</p>
    <p>flex25</p>
</div>
// css代码
.container-aContent-spacearound{
    display: flex;
    flex-wrap: wrap;
    align-content: space-around;
}

6.stretch

flex1

flex2

flex3

flex4

flex5

flex6

flex7

flex8

flex9

flex10

flex11

flex12

flex13

flex14

flex15

flex16

flex17

flex18

flex19

flex20

flex21

flex22

flex23

flex24

flex25

代码:

// html代码
<div class="parent-container container-aContent-stretch">
    <p>flex1</p>
    <p>flex2</p>
    <p>flex3</p>
    ···            //多个p元素
    <p>flex23</p>
    <p>flex24</p>
    <p>flex25</p>
</div>
// css代码
.container-aContent-stretch{
    display: flex;
    flex-wrap: wrap;
    align-content: stretch;
}

flex容器中子元素的属性

为了减少重复代码,且方便读者看懂,该标题(flex容器中子元素的属性)下的所有代码的css均基于以下两个class属性

.child-container{
    border: 1px solid #D53419;
    background-color: #50E9EE;
    width: 350px;
    height: 100px;
    display: flex;
}
.child-container>p{
    background-color: #dbc21d;
    height: 50px;
}

flex子元素具有6个相关的属性,可以将属性设置在子元素上。

序号 属性 含义
1 order 定义子元素的排列顺序。数值越小,排列越靠前,默认为0。
2 flex-grow 定义子元素的放大比例,如果存在剩余空间,也会等比例放大,默认为0。
3 flex-shrink 定义子元素的缩小比例,如果空间不足,该子元素将缩小,默认为1。
4 flex-basis 定义在分配多余空间之前,子元素占据的水平或垂直空间,默认为auto。
5 flex 是flex-grow, flex-shrink 和 flex-basis的简写,后两个属性可选,默认值为0 1 auto。
6 align-self 允许单个子元素有与其他子元素不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于默认值stretch。

order

定义项目的排列顺序。数值越小,排列越靠前。

flex1

flex2

flex3

flex4

flex5

代码:

// html代码
<div class="child-container childorder">
    <p style="order: 36">flex1</p>
    <p style="order: 18">flex2</p>
    <p style="order: 5">flex3</p>
    <p style="order: 9">flex4</p>
    <p style="order: 6">flex5</p>
</div>
// css代码
.childorder>p{
    width:50px;
    margin: 5px;
}

flex-grow

如果所有子元素的flex-grow属性都为1,则它们将等分一排空间.
如果一个子元素的flex-grow属性为2,其他子元素都为1,则前者占据的宽度是其他子元素的2倍。
如果想要flex-grow样式正常执行,则不能给子元素定义宽度width!否则样式会与预想中的不同

代码:

// html代码
<div class="child-container">
    <p style="background-color:#ff7f50;flex-grow: 1;"></p>
    <p style="background-color:#2bafd9;flex-grow: 2;"></p>
    <p style="background-color:#f0e68c;flex-grow: 1;"></p>
    <p style="background-color:#ffc0cb;flex-grow: 3;"></p>
</div>

flex-shrink

如果所有子元素的flex-shrink属性都为1,当空间不足时,所有子元素都将等比例缩小。如果一个子元素的flex-shrink属性为0,其他子元素都为1,则空间不足时,前者不缩小。

代码:

// html代码
<div class="child-container child-flexshrink">
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 0;"></p>
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 1;"></p>
    <p style="flex-shrink: 1;"></p>
</div>
// css代码
.child-flexshrink>p{
    height: 50px;
    width: 50px;
    margin: 5px;
    background-color:#be5ad1;
}

flex-basis

定义在一排空间未被占满之前,子元素的width或height的值(例如100px),定义之后,子元素将占据固定空间。

代码:

// html代码
<div class="child-container child-flexshrink">
    <p></p>
    <p style="flex-basis: 100px;"></p>
    <p></p>
    <p></p>
</div>
// css代码
.child-flexshrink>p{
    height: 50px;
    width: 50px;
    margin: 5px;
    background-color:#be5ad1;
}

flex

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

align-self

该属性有6个属性值

序号 属性值
1 flex-start
2 flex-end
3 center
4 baseline
5 stretch
6 auto

属性值含义可查看 align-items 与align-items属性值的含义相同(auto除外);

align-self默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch属性值。

代码:

// html代码
<div class="child-container child-alignself">
    <p></p>
    <p style="align-self: flex-end;"></p>
    <p></p>
    <p></p>
</div>
// css代码
.child-alignself>p{
    height: 50px;
    width: 50px;
    margin: 5px;
    background-color:#be5ad1;
}

总结

flex弹性布局的诞生,解决了传统CSS布局的很多问题,而且使用起来更加方便。

我们回到之前最开始的那个问题,如果列表是动态的话,使用flex是不是很方便?

// html代码
<div class="newlist">
    <ul class="new-ul">
        <li>列表1</li>
        <li>列表2</li>
        <li>列表3</li>
    </ul>
</div>
// css代码
.newlist{
    border: 1px solid #D53419;
    background-color: #50E9EE;
    width: 250px;
    height: 250px;
}
.new-ul{
    margin-top: 0px;
    height: 250px;
    display: flex;
    flex-wrap: wrap;
    align-content: space-around;
}
.new-ul>li{
    width: 100%;
}

三个列表的情况

  • 列表1
  • 列表2
  • 列表3

四个列表情况

  • 列表1
  • 列表2
  • 列表3
  • 列表4

五个列表情况

  • 列表1
  • 列表2
  • 列表3
  • 列表4
  • 列表5

无需一直修改css文件,非常方便!

本章完~


转载请注明: MrLi css弹性布局-flex布局

上一篇
Linux常用命令 Linux常用命令
本文主要介绍Linux常用的一些基本命令。 查看系统版本:cat /etc/redhat-release 或 cat /etc/issue 删除文件: rm -f /var/log/httpd/access.log 将会强制删除/v
2018-08-01
下一篇
数据结构的相互转换 数据结构的相互转换
本文介绍 Map与Array,Object,JSON之间的相互转换 Map转为ArrayMap转为Array,直接使用es6引入的扩展运算符(…)。 let myMap = new Map().set(true, 7).set({foo:
2018-01-06
目录