用自己的理解记录下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属性深入理解]
参考链接:
