用自己的理解记录下flex的知识点,部分文字描述是在学习其他作者分享的文章觉得很好而使用的,不是无脑搬运,是学习和借鉴!
- 一、基本原理
- 二、flex容器和项目
- 三、轴线
- 四、flex属性
-
- [4.1 属性汇总](#4.1 属性汇总)
- [4.2 属性分类](#4.2 属性分类)
- [4.3 属性详解](#4.3 属性详解)
-
- (1)flex-direction
- (2)flex-wrap
- (3)flex-flow
- (4)justify-content
- (5)align-items
- (6)align-content
- (7)flex-grow
- [(8) flex-shrink](#(8) flex-shrink)
- [(9) flex-basis](#(9) flex-basis)
- [(10) flex](#(10) flex)
- (11)align-self
- [(12) order](#(12) order)
- 五、flex习题
一、基本原理
- 弹性布局,伸缩布局、弹性盒子多种叫法。
- 通过给父元素设置flex属性,来控制子元素的排列方式。
- 一个容器包裹着多个子项目,通过配置不同属性,实现各种各样排列分布。
容器可理解为:为显示内容(子项目)分布提供的空间。
属性可以控制子项目在容器内排兵布阵(显示方式)
二、flex容器和项目
- 当元素
display:flex
它就成了一个flex
容器。 - 主轴方向默认是从左到右排列为一行(
flex-direction:row
) - 项目在主轴方向上不会被拉伸(填满容器),如果项目加起来超过容器宽度,默认会自动缩小项目,不会另起一行。
- 项目在交叉轴上如果没有设置高度,会被拉伸填满容器。如果容器也没有设置高度,最高的项目高度则为容器高度。
三、轴线
- flex轴线:两根轴线,主轴和交叉轴。
- 由方向属性 flex-diretion 控制主轴的方向。(默认为row,从左到右)
- 主轴:控制项目的排列的方向(上下左右)
- 交叉轴:配合主轴实现对齐方式。永远垂直于主轴。
所有的属性都围绕轴线展开,必须理解轴线!(示意图)
四、flex属性
4.1 属性汇总
属性名 | 描述 | |
---|---|---|
1 | flex-direction | 项目排列方式 |
2 | flex-wrap | 项目宽度超出容器时是否换行 |
3 | flex-flow | 复合属性。flex-direction 和 flex-wrap 两个属性简写 |
4 | flex-grow | 项目扩展比例。默认值为0,即如果存在剩余空间,也不放大 规定项目将相对于其他灵活的项目进行扩展的量 |
5 | flex-shrink | 项目缩小比例。默认值为1,即如果空间不足,该项目缩小 规定项目将相对于其他灵活的项目进行收缩的量 |
6 | flex-basis | 项目的基准值(初始值) |
7 | flex | flex-grow 和 flex-shrink 和 flex-basis 简写属性 |
8 | justify-content | 设置项目在主轴方向上的对其方式 |
9 | align-items | 设置项目在交叉轴方向上的对其方式 |
10 | align-content | 修改 flex-wrap属性的行为,类似align-items。但它设置的是行对齐,不是子元素对其 |
11 | align-self | 项目上使用,覆盖容器的align-items属性 |
12 | order | 设置项目的排列顺序 |
4.2 属性分类
1. 容器的属性(在容器上使用的属性)
容器属性名 | 说明 | |
---|---|---|
1 | flex-direction | 项目排列方式(决定主轴方向) |
2 | flex-wrap | 项目换行(默认不换行) |
3 | flex-flow | flex-direction 和 flex-wrap合并简写 |
4 | justify-content | 项目在主轴上的对齐方式 |
5 | align-items | 单行项目在交叉轴上的对齐方式 |
6 | align-content | 多行项目在交叉轴上的对齐方式 |
2. 项目的属性 (在项目上使用的属性)
项目属性名 | 说明 | |
---|---|---|
1 | flex-grow | 定义项目的放大比例 ,默认为0(不放大) |
2 | flex-shrink | 定义项目的缩小比例,默认为1(缩小) |
3 | flex-basis | 定义项目初始化占据主轴空间的尺寸,默认为auto |
4 | flex | 复合属性,flex-grow、flex-shrink、flex-basis的简写,默认为 0 1 auto |
5 | align-self | 单个项目在交叉轴上的对齐方式,默认为auto |
6 | order | 定义项目的排列顺序(前后顺序) |
4.3 属性详解
(1)flex-direction
bash
flex-direction:row | column | row-reverse | column-reverse;
- 设置项目的排列方式。(项目跟着主轴来排列)
- 指定主轴的方向
row
:默认。横向排列,从左到右。(起点在左)column
:竖向排列,从上到下。(起点在上)row-reverse
:横向排列,从右到左。(起点在右)column-reverse
:竖向排列,从下到上。(起点在下)
(2)flex-wrap
bash
flex-wrap:nowrap | wrap | wrap-reverse;
- 设置项目换行
- 默认情况下,项目都排列在一行(一条轴线上)。不会换行。
nowrap
:默认。不换行。wrap
:换行。项目大小超出一行,换到下一行。从上往下排列。wrap-reverse
:前后反转换行。项目大小超出一行,换到下一行。从下往上排列。
(3)flex-flow
bash
flex-flow:<flex-direction> <flex-wrap>;
- 复合属性。
flex-direction
和flex-wrap
简写。- 默认值:
flex-flow: row nowrap;
//flex-direction:row;
flex-wrap:nowrap;
(4)justify-content
bash
justify-content:flex-start | flex-end | center | space-between | space-around | space-evenly;
- 定义项目在主轴上的对齐方式。
- 默认值:
justify-content: flex-start;
flex-start
:默认值,左对齐。(主轴起始位置对齐,默认方向下是左上角对齐)flex-end
:右对齐。(主轴结束位置对齐,默认方向下是右上角对齐)center
: 居中。(主轴位置居中对齐,默认方向下就是水平居中)space-between
: 两端对齐,项目中间间距相等。(主轴位置上两端对齐,两端无间距)space-around
: 每个项目两侧间距相等,两端有间距,两端间距为项目间距的一半。(主轴位置上两端对齐,两端有间距)space-evenly
: 在弹性空间内均匀的分配间距,容器两端和项目之间的间距相等。(主轴位置上两端对齐,两端有间距,两端间距与项目间距相等)
(5)align-items
bash
align-items:stretch | flex-start | flex-end | center | baseline;
- 定义项目在交叉轴上的对齐方式。(单行)
- 在项目为单行时适用。
stretch
: 默认值。项目被拉伸为容器大小,在没有设置项目的固定高度下。(交叉轴的剩余空间)flex-start
:项目沿交叉轴起始位置对齐。(按默认方向就是左上角对齐)flex-end
: 项目沿交叉轴终点位置对齐。(按默认方向就是左下角对齐)center
: 项目在交叉轴方向居中对齐。(按默认方向就是垂直居中)baseline
: 项目在交叉轴方向沿项目第一行文字基线对齐。
(* strech
案例应该为:所有块都充满屏幕,此处设置了固定高度,如下图)
(6)align-content
bash
align-content:stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;
- 定义多行项目(多根主轴线)对齐方式。(常在产生换行时使用)
- 类似
justify-content
,不过justify-content
控制的是项目与项目之间的空间分配,align-content
控制的是行与行之间的空间分配(我理解的就是主轴线的排列对齐方式)stretch
: 默认值。交叉轴上的每一个轴线被平均分配高度。轴线上的项目被拉伸适应于该轴线,在没有设置项目的固定高度下。flex-start
: 所有行在交叉轴方向上,沿交叉轴起始位置对齐。(按默认方向就是所有行从上往下,从左到右依次排列。左上角)flex-end
: 所有行在交叉轴方向上,沿交叉轴结束位置对齐。(按默认方向就是所有行以左下角为起点,从上往下,从左到右依次排列)center
: 所有行在交叉轴方向上,居中对齐。(按默认方向就是所有行垂直居中于交叉轴上)space-between
: 所有行在交叉轴方向上两端对齐,两端无间距,中间间隔相等。(按默认方向就是在交叉轴上垂直的两端对齐)space-around
: 所有行在交叉轴方向上两端对齐,两端和行之间都有间距,两端的间距是行间距一半。(按默认方向就是在交叉轴上垂直的排列。)space-evenly
: 所有行在交叉轴方向上两端对齐,两端和行之间都有间距,所有间距相等。(按默认方向就是在交叉轴上垂直排列,两端与行间距一致)
(7)flex-grow
bash
flex-grow:<number [0,∞]>;
- 定义
flex
项目增长因子【定义项目在主轴方向上的放大比例,默认为0。(不放大)】- 当主轴(父元素)还有剩余空间时,如何分配这些空间。
- 该属性规定了在容器中分配剩余空间的相对比例。剩余空间是flex容器大小减去所有flex项目大小加起来的大小。
- 项目的
grow
系数一样,所有项目将剩余空间按相同比例分配。- 通常与
flex-shrink
和flex-basis
一起使用
增长空间分配计算规则
bash
1. 求出可分配的剩余空间
可分配空间 = 容器总宽度 - 项目总宽度;
2. 增长因子总和
flex-grow总和
3. 根据自身的增长因子所占比例与宽度计算出最终增长后的宽度
项目最终宽度 = 项目自身宽度 + 可分配空间 * (自身增长因子/增长因子总和)
例1:项目的 flex-grow 属性都为1,他们将等分剩余空间。
bash
根据公式可列出
// 可分配空间
600 - 60 * 5 = 300;
// 增长因子总和
1+1+1+1+1 = 5;
// 项目最终宽度
60 + (300 * (1/5)) = 120
例2:如果一个项目的 flex-grow:2,其他项目都为1,则该项目所占的剩余空间比其他项目多一倍
bash
根据公式可列出
// 可分配空间
600 - 60 * 5 = 300;
// 增长因子总和
1+2+1+1+1 = 6;
// 项目最终宽度
1. 60 + (300 * (1/6)) = 110 // flex-grow: 1 的宽度
2. 60 + (300 * (2/6)) = 160 // flex-grow: 2 的宽度
(8) flex-shrink
flex-shrink:<number[0,∞]>;
- 定义flex项目收缩因子(收缩规则),默认为1(收缩)。不可为负值。
- 默认为1: 即如果空间不足,该项目将缩小。
- 在项目宽度之和大于容器时才会发生收缩,收缩大小依据
flex-shrink
值。- 当剩余空间不够时让各个子元素收缩以适应有限空间
- 该属性处理浏览器在计算弹性元素的
flex-basis
值,并发现他们太大以至于无法适应弹性容器时,flex-shrink
有正值,元素就会收缩以至于他们不会溢出容器。
收缩空间分配计算规则
bash
1. 计算可分配的收缩空间
可分配空间 = 项目总宽度 - 容器总宽度;
2. 计算项目收缩比例宽度
项目宽度 * 项目收缩值(shrink值)
3. 总收缩比例宽度
各个项目收缩比例之和
4. 项目自身的收缩比例值
项目收缩比例宽度 / 总收缩比例宽度
5. 计算项目最终的宽度
1)计算被分配的缩减宽度
可收缩的空间 * 项目自身收缩比例值
2)计算最终缩减后的项目宽度
项目宽度 - 分配的缩减宽度
例1:计算溢出的宽度,也就是可收缩的空间宽度
例2:容器宽度为600px,项目宽度为130,项目数量5,shrink值分别为:1,2,3,1,1
bash
套用计算公式
1. 可收缩的空间
130 * 5 - 600 = 50;
2. 计算每个项目的收缩比例宽度
130 * 1 = 130;
130 * 2 = 260;
130 * 3 = 390;
130 * 1 = 130;
130 * 1 = 130;
3. 计算总收缩比例宽度
130 + 260 + 390 + 130 + 130 = 1040;
4. 计算项目自身的收缩比例值
130 / 1040 = 0.125;
260 / 1040 = 0.25;
390 / 1040 = 0.375;
130 / 1040 = 0.125;
130 / 1040 = 0.125;
5. 计算最终宽度
a) 计算被分配的缩减宽度
50 * 0.125 = 6.25;
50 * 0.25 = 12.5;
50 * 0.375 = 18.75;
50 * 0.125 = 6.25;
50 * 0.125 = 6.25;
b) 最终宽度
130 - 6.25 = 123.75;
130 - 12.5 = 117.5;
130 - 18.75 = 111.25;
130 - 6.25 = 123.75;
130 - 6.25 = 123.75;
最终的计算结果为:
shrink:1 123.75
shrink:2 117.5
shrink:3 111.25
总结:计算弹性元素的收缩宽度。
弹性元素的宽度 - 弹性元素宽度shrink比例值 / 权重收缩宽度 * 可收缩宽度
(9) flex-basis
bash
flex-basis:<length> | auto;
- 定义项目的初始化尺寸(基准值),默认为
auto
。(项目未定义大小,会解析为内容大小。项目定义了200px宽度,auto值就为200px)- flex布局中,
flex-basis
优先级高于width
。(同时设置flex-basis值与width值,生效的时flex-basis值)flex-basis
值不是auto
时,width
属性会被忽略。flex-basis
值为auto
或者0
时,元素的大小由自身内容决定。
auto
: 尺寸为最大内容宽度;0
:尺寸为最小内容宽度。- 设置了basis值,元素在增长时:可以同其他元素一样扩张,初始值和最小值为设置的basis值。 元素在收缩时:可以同其他元素一样收缩,初始值和最大值为设置的basis值。
- 这里有一个疑问,也没有找到很详细的说明,有知道的吗,请分享。flex-basis:auto,flex-basis:0;异同和具体计算原理和尺寸说明。
flex-basis:auto;
在设置了元素宽度的前提下,使用
flex-basis:auto
, auto取值为设置的宽度值。
flex-basis:0;
- 以元素内容为基准,折叠到最小可能的宽度。
- 元素设置的宽度会失效,取值为
flex-basis:0
,也就是元素内容最小宽度
(10) flex
bash
flex: <flex-grow> [<flex-shrink>] [<flex-basis>];
- 复合属性,
flex-grow
、flex-shrink
、flex-basis
的简写,默认为 0 1 auto。- 后面两个参数为可选参数
- 定义项目分配剩余空间,用flex表示项目占多少份数
1. 关键字简写
flex: initial;
等同于flex:0 1 auto;
也就是默认值。不拉伸,可收缩,宽度为内容宽度。flex: auto;
等同于flex: 1 1 auto;
可拉伸,可收缩,宽度为内容宽度。flex: none:
等同于flex:0 0 auto;
不拉伸,不收缩,宽度为内容宽度。flex:<number>;
flex:2;
等同于flex: 2 1 0;
2. 多种简写方式
- 根据值的类型判断赋值的属性
- 默认值:
flex: 0 1 auto;
flex值的类型会改变默认属性值。
例:flex:1
,虽然设置的是flex-grow
的值,但是此时,flex-basis
的值为0%
;
2.1 一个值
不带单位意为设置 flex-grow
值
bash
flex:1; // flex: 1 1 0%;
带单位意为设置 flex-basis
值
bash
flex:80px || flex:80%: // flex:1 1 80px;
2.2 两个值
不带单位的两个值为设置:flex-grow
和 flex-shrink
bash
flex:1 0; // flex: 1 0 0%;
带单位的两个值为设置: flex-grow
和 flex-basis
(不分先后顺序,用类型去判断)
bash
flex: 80px 1; // flex:1 1 80px;
2.3 三个值
bash
flex: 80px 2 3; // flex:2 3 80px;
一个是错误的写法,具体原因不太清楚
flex: 2 80px 3;
(11)align-self
bash
align-self: auto | flex-start | flex-end | center | baseline | stretch;
- 单个项目在交叉轴上的对齐方式,默认为
auto
。- 优先级高于
align-items
; align-items 是控制所有项目交叉轴对齐方式。- 属性值与
align-items
取值一致,多一个:auto
;- 没有文化的比喻就是做人群中最靓的仔。
例1. 项目上设置align-self
- 容器上设置交叉轴对齐方式为:
align-items: flex-start;
- 项目2单独设置:
align-self:center;
(12) order
bash
order:<number>;
- 定义项目在主轴上的排列顺序(前后顺序)。
- 默认值:0。
- 可以取负值。
例: 项目2设置为-1,使其排列在首位
五、flex习题
答案在"参考链接": [CSS flex属性深入理解]
参考链接: