盒子
盒子
文章目录
  1. 背景
  2. 初识flex
  3. 什么是flex布局
  4. 了解flex
    1. 小试牛刀
    2. flex基础模型
    3. 作用在flex容器上面的属性
      1. flex 容器的单个属性
      2. flex容器的复合属性
    4. 作用在子元素(item上的属性)
      1. flex item 单个属性
      2. flex item 综合属性
  5. 拓展延伸

flex布局

背景

在网页开发当中,我们经常会面临这样一个场景:让一个块级元素在其父容器中垂直水平居中。如何实现这样一个功能呢?我们先来看看传统的解决方案:

  • 方案1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  html:
<div class="container">
<div class="son-container">
我是子元素!!!
</div>
</div>

css:

.container {
width: 400px;
height: 400px;
margin: 50px auto;
background: yellow;
position: relative;
}
.son-container {
width: 200px;
height: 200px;
background: pink;
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
  • 方案2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

html:

<div class="container">
<div class="son-container">
我是子元素!!!
</div>
</div>

css:

.container {
width: 400px;
height: 400px;
margin: 50px auto;
background: yellow;
position: relative;
}
.son-container {
width: 200px;
height: 200px;
background: pink;
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -100px;
}

以上两种方案都能解决水平垂直居中问题,但是有一个前提就是子元素的宽高就是已知的。但是在很多时候子元素的高度并不是固定的,而是由内容撑开的,所以上述两种方式就出现了局限性。

  • 方案3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
   html:

<div class="container">
<div class="son-container">
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
<p>段落4</p>
</div>
<img src="./images/cat.jpg" alt="">
</div>

css:
.container {
width: 400px;
height: auto;
margin: 50px auto;
background: yellow;
position: relative;
}
.container img {
width: 100%;
height: auto;
display: block;
}
.son-container {
width: 200px;
height: 200px;
background: pink;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

这种方式也能解决垂直水平居中的问题,并且子元素的高度可以不固定。

虽然上述这些方案可以做到垂直水平居中,但还是有其局限性和不便利性(显而易见的一点就是必须要用到定位),那么有没有一种方式可以优雅便捷的实现这一功能呢?答案是肯定的,那就让我们一起来认识下flex布局吧。

初识flex

什么是flex布局

一种弹性布局,被定义了display:flex属性的元素叫做伸缩容器,而其子元素也就变成伸缩项目(flex item)。伸缩容器中的子元素可以在垂直或者水平任意方向上进行排列,同时也能应需求伸缩尺寸。

浏览器对flex的支持程度:

如图可以看出浏览器支持程度还是不错的。

了解flex

小试牛刀

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
html: 
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
<li>列表5</li>
<li>列表6</li>
</ul>

css:
ul {
width: 1000px;;
height: auto;
margin: 100px auto;
background: yellow;
display: flex;
}
li {
width: 100px;
height: 50px;
margin: 10px;
background: pink;
list-style: none;
}

先看看效果:

我们都知道任何块级元素,没做特殊处理的情况下都是从上往下排列,而在本例中,仅仅只是给父元素ul加了个display:flex,li元素就直接从左往右进行排列了,是不是瞬间觉得好神奇,好强大。那接下来我们就来看看flex有哪些强大的属性。

flex基础模型

在了解flex属性之前还是有必要了解下图的:

默认情况下水平方向为主轴,垂直方向上为侧轴。
在实际开发过程中主轴的方向和项目排列的方向保持一致,即:

  • flex-direction取值为row/row-reverse 则主轴为水平方向,row(从左往右),row-reverse(从右往左) ;侧轴为垂直方向,从上往下;
  • flex-direction取值为column/column-reverse 则主轴为垂直方向,column(从上往下),column-reverse(从下往上);侧轴为水平方向,从左往右;

作用在flex容器上面的属性

flex 容器的单个属性

1、flex-direction 定义子元素(flex item)的排列方式,四个取值

  • row 子元素从左往右排列
  • column 子元素从上往下排列
  • row-revers 从右往左排列
  • column-reverse 从下往上排列

让我来看看对比效果图吧:

2、flex-wrap 用来处理当容器放不下所有的flex item时的情况,类似与文字的换不换行。

  • wrap 当flex容器放不下所有item项时会换行排列
  • nowrap Flex项目在Flex容器内不换行排列,不换行但是flex item的宽度会发生变化
  • wrap-reverse 当flex容器放不下所有item项时会换行排列,但是和wrap的方向相反

让我来看看对比效果图吧:

3、justify-content 设置flex item在主轴上面的对齐方式

  • flex-start 主轴方向的起始位置对齐
  • flex-end 主轴方向的结束位置对齐
  • center 在主轴上面居中对齐
  • space-between 两端对齐,两端item与边缘间距为0,剩余间距平均分配
  • space-around 让每个flex项目都有相同的间距,最边上item的间距是其他相邻item间距的一半。

文字描述还是略显晦涩模糊,直接上图:

4、align-items 设置flex item 在侧轴上面的对齐方式

  • flex-start 关于侧轴方向的起始位置对齐
  • flex-end 关于侧轴方向的结束位置对齐
  • center 关于侧轴方向的中间位置对齐
  • stretch 在侧轴方向上拉伸item的宽/高度至容器大小
  • baseline 关于item排列方向上第一个项目的基线对齐

对比图:

5、align-content 只有当设置了flex-wrap: wrap属性时才会生效。用来定义多行item的在侧轴上的排列方式

  • stretch 拉伸flex item项目(前提侧轴方向上的边没有设置长度,如果设置了,就用间距平分容器空间), 沿侧轴适应flex容器可用空间。
  • flex-start 关于侧轴方向的起始位置对齐
  • flex-end 关于侧轴方向上的终点位置对齐
  • center 关于侧轴方向上居中对齐

对比图:

flex容器的复合属性

1、flex-flow 该属性是flex-direction和flex-wrap的复合属性

  • 语法格式: flex-flow: flex-direction flex-wrap;
  • 例子: flex-flow: row wrap;

作用在子元素(item上的属性)

flex item 单个属性

1、order 定义flex项目在容器中的排列顺序,flex项目可以根据order从低到高排列

  • 取值:数值。可正可负,默认为0
  • 例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    html: 
    <li style="background: red; font-size: 12px;" >列表1</li>
    <li style="background: green">列表2列表2列表2列表2</li>
    <li style="background: orange">列表3</li>
    <li style="background: blue">列表4</li>

    css:
    ul {
    width: 500px;;
    height: 300px;
    margin: 100px auto;
    background: yellow;
    display: flex;
    flex-direction:column;
    flex-wrap: wrap;
    align-content: stretch
    }
    li {
    width: 100px;
    height: 50px;
    margin: 5px;
    background: pink;
    list-style: none;
    font-size: 18px;
    }
    li:nth-child(1) {
    order: 2;
    }

效果图:

2、flex-grow: 设置元素的生长因子(当子元素的总宽/高度小于父容器的宽度时,如何分配父容器的空间)

  • 默认值: 0,表示不伸张;
  • 取值: 0 或者 大于0的正数
  • 计算公式:itemA 的 宽/高 实际取值 = itemA原(宽|高)取值 + 父容器剩余空间*比例因子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
html:
<ul>
<li style="background: red;" >列表1</li>
<li style="background: green">列表2</li>
</ul>

css:
ul {
width: 500px;;
height: 300px;
margin: 100px auto;
background: yellow;
display: flex;
flex-direction:row;
align-items: flex-start;
}
li {
width: 200px;
height: 200px;
background: pink;
list-style: none;
}
li:nth-child(1) {
flex-grow: 2;
}
li:nth-child(2) {
flex-grow: 3;
}

效果图如下:

3、flex-shrink: 设置元素的收缩因子【当子元素的总宽/高度(取决于主轴方向)大于父容器的宽/高值时,如何缩小自己的宽/高值的】

  • 默认为1
  • 取值为 0 或者任意正数;取0时表示不收缩
  • 计算公式 itemA = itemA 原 宽|高 - 子元素超出的长度 * 比例因子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
html:
<li style="background: red;">列表1</li>
<li style="background: green">列表2</li>

css:
ul {
width: 500px;;
height: 300px;
margin: 100px auto;
background: yellow;
display: flex;
flex-direction:row;
align-items: flex-start;
}
li {
height: 200px;
background: pink;
list-style: none;
}
li:nth-child(1) {
width: 200px;
flex-shrink: 2;
}
li:nth-child(2) {
width: 400px;
flex-shrink: 3;
}

效果图如下:

4、flex-basis 指定flex元素在主轴方向上的宽/高(取决于主轴方向)值,它会使得被设定了width/height的属性值失效。

  • 默认为auto;
  • 设定值时需要带上单位,单位和width属性的单位一样,即 %|| em|| rem || px …
  • 当设置了flex-basis值之后,item 主轴方向上的边长取值为flex-basis,width/height 会失效。
  • 实例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    html: 
    <li style="background: red;">列表1</li>
    <li style="background: green">列表2</li>

    css:
    ul {
    width: 500px;;
    height: 300px;
    margin: 100px auto;
    background: yellow;
    display: flex;
    flex-direction:row;
    align-items: flex-start;
    }
    li {
    height: 200px;
    background: pink;
    list-style: none;
    }
    li:nth-child(1) {
    width: 150px;
    flex-basis: 160px;
    }
    li:nth-child(2) {
    width: 150px;
    flex-basis: 280px;
    }

效果图如下:

5、align-self 用来改变某一个(单个)flex item 在侧轴方向上的位置,而不影响相邻的弹性项目。

  • auto 取值会被设置成父容器的align-items的值,如果父容器没有设置align-items属性值,那么则会取值为stretch
  • flex-start 被设置的flex item元素会被对齐到侧轴的首端
  • flex-end 被设置的flex item元素会被对齐到侧轴的末端
  • center 被设置的flex item元素会被对齐到侧轴的中间位置
  • baseline 沿基线对齐(设置在一组item项目上面才能看到效果)
  • stretch 被设置的元素将会基于容器的宽和高,按照自身 margin box 的 cross-size 拉伸

对比图如下:

flex item 综合属性

1、flex 是flex-grow、flex-shrink、flex-basis 三个属性的符合属性

  • 默认取值 flex: 0 1 auto;
  • 用法: flex: flex-grow flex-shrink flex-basis;

拓展延伸

支持一下
扫一扫,支持晓晓
  • 微信扫一扫
  • 支付宝扫一扫