[toc]

前言

详细记录flex弹性布局的具体属性和常考题。
关键词:flex属性、

flex概念

弹性盒子是一种按行或者按列布局元素的一种以为布局方法,容器里面的元素可以膨胀填充额外的空间,收缩来适应更小的空间,适用于任何元素。

元素使用flex布局就会在内部形成BFC,目前flex已经适配所有常规浏览器

拓展:BFC

BFC:块级格式化上下文,是一个完全独立的空间,里面的子元素不会影响到外面的布局。

触发BFC的方式:

  • overflow:hidden
  • display:inline-block,table-cell,flex
  • position:absolute,fixed

BFC解决的问题:

  • 高度塌陷
  • margin边距重叠

flex和inline-flex

display有两种设置方式:flex和inline-flex。

区别在于:
flex元素和宽度是父容器的100%
inline-flex是所有元素的宽度和

那么在元素溢出的情况下是怎么样呢?

可见inline-flex会撑大flex容器,造成溢出

使用inline-flex的时候,注意配合min-width和min-height一起使用。不建议显示设置height和width

常见使用场景


可以总结为 整个容器的设置flex 不占整个容器的或者容器的部分 设置为inline-flex

主轴和交叉轴

flex布局有两个轴的概念:主轴和交叉轴。水平的叫做主轴,垂直的叫做交叉轴。主轴的开始位置叫做start 结束叫做end 交叉轴也是如此。
flex布局的元素称为容器container,他的所有子元素都是一个项目item

容器的属性

flex-direction

  • row:水平左 左对齐
  • row-reverse:水平右 右对齐
  • column: 垂直上 上对齐
  • column-reverse: 垂直下 下对齐

场景

由于默认会携带flex-direction:row(代码冗余)所以在非row的时候再设置flex-direction做布局算法优化

flex-wrap

默认情况下元素不换行nowrap,加了wrap属性之后,会换行

  • nowrap 不换
  • wrap 换行
  • wrap-reverse 换行 第一行在下方
    eg
    1
    2
    5 6 null null
    1 2 3 4

flex-flow

是direction和wrap属性的简写 默认为row nowrap
只设置一个值的时候 看匹配哪个属性值 来取值

1
flex-flow: row || nowrap

justify-content

描述了元素在主轴上面的对齐方式

  • flex-start 左对齐
  • flex-end 右对齐
  • center 居中
  • space-around 每个项目两端的间隔相等 意味着第一个和最后一个元素两侧的宽度不等
  • space-between 两端对齐 项目之间的间隔相等
  • space-evenly: 项目的间隔和容器的间隔相等

align-items

描述元素在交叉轴上面的对齐方式

  • flex-start 上对齐
  • flex-end 下对齐
  • center 居中
  • baseline 项目第一行文字的基线对齐
  • stretch 默认 如果没设置高度或者auto 则占满整个容器的高度

align-content

定义了多根轴线的对齐方式 前提设置flex-wrap:wrap 否则不生效

  • flex-start 交叉轴起点
  • flex-end 交叉轴中终点
  • center 中点
  • space-between 两端对齐 轴线之间平均分
  • space-around 轴线间间隔相等
  • stretch 默认值 占满整个交叉轴

gap

gap用来控制flex项目之间的间距,但会忽略flex项目与flex容器边缘的间距

项目的子项属性

order

定义项目的排列顺序 数值越小越前 默认0 可以是负数

场景:

flex-grow

定义了容器中剩余空间应该有多少分配给项目,最终的宽度为:自身宽度+容器剩余空间分配宽度 该属性的最大值是1 超过1按1来拓展

flex-shrink

该属性指定了flex元素的收缩规则。只在项目的元素宽度和大于容器的时候才会触发。收缩的大小是依据该属性的值 默认为1

eg 两个div 第一个div宽度200 第二个div宽度300 容器400
容器设置了flex布局 两个div的shrink都设置为1
那么此时 两个div500大于400 所以触发收缩

那么收缩后子项的宽度怎么计算呢?
有公式如下

  1. 所有子项宽度和-容器的宽度=500 - 400 = 100
  2. 第一个子项的占比 2/5 第二个子项的占比 3/5
  3. 第一个子项的宽度为200-2/5*100=160,第二个为:300-3/5*100=240

flex-basis

指定子项目的在主轴的初始化大小,优先级高于自身宽度width

1
flex-basis: 0 | 100% | auto | <length>

flex

flex是flex-grow flex-shrink 和 flex-basis的简写
单值的时候 数值被当作flexgrow 一个有效的宽度值被当作basis
双值的时候 一个无单位的数 被当成shrink 一个有效的宽度值被当成basis
三值 略

默认 0 1 auto

取值,除了自定义的三种外:
auto根据自身的width和height来确定比例 相当于1 1 auto
initial相当于0 1 auto
none 0 0 auto

align-self

允许单个项目有和其他项目不一样的对齐方式,可以覆盖align-items属性,默认auto表示继承align-items 如果没有父元素 则等于stretch

常见使用场景

Flex项目上的 margin

在Flex项目显式设置 margin 的值为 auto 可以灵活的控制单个Flex项目在Flex容器中的位置:

比如像下图这样的效果,使用 margin-left: auto 就非常的实用:

常见场景

等高布局

左侧宽度固定 右侧宽度自适应布局(常见的tob系统布局,左侧菜单树右侧内容)
粘性页脚

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
35
36
37
38
39
40
<div class="flex__container">
<span class="coupon"></span>
<span class="divider"></span>
<span class="price">&yen;1000</span>
</div>



.flex__container {
display: inline-flex;
min-width: 200px;
height: 60px;

border: 1px solid rgba(255, 0, 54, 1);
background-color: rgba(255, 0, 54, 0.1);
border-radius: 4px;
color: #ff0036;
font-size: 24px;
font-weight: 400;
}

.flex__container > span {
display: inline-flex;
justify-content: center;
align-items: center;
}

.divider {
border-right: 1px dashed currentColor;
}

.coupon {
min-width: 50px;
}

.price {
flex: 1;
min-width: 0;
padding: 0 10px;
}