深入浅出Flex弹性布局
[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 换行 第一行在下方
eg1
25 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 所以触发收缩
那么收缩后子项的宽度怎么计算呢?
有公式如下
- 所有子项宽度和-容器的宽度=
500 - 400 = 100
- 第一个子项的占比
2/5
第二个子项的占比3/5
- 第一个子项的宽度为
200-2/5*100=160
,第二个为:300-3/5*100=240
flex-basis
指定子项目的在主轴的初始化大小,优先级高于自身宽度width1
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 autonone
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">¥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;
}