css --- 让人上头的flex

用自己的理解记录下flex的知识点,部分文字描述是在学习其他作者分享的文章觉得很好而使用的,不是无脑搬运,是学习和借鉴!

一、基本原理

  1. 弹性布局,伸缩布局、弹性盒子多种叫法。
  2. 通过给父元素设置flex属性,来控制子元素的排列方式。
  3. 一个容器包裹着多个子项目,通过配置不同属性,实现各种各样排列分布。
    容器可理解为:为显示内容(子项目)分布提供的空间。
    属性可以控制子项目在容器内排兵布阵(显示方式)

二、flex容器和项目

  1. 当元素 display:flex 它就成了一个flex容器。
  2. 主轴方向默认是从左到右排列为一行(flex-direction:row
  3. 项目在主轴方向上不会被拉伸(填满容器),如果项目加起来超过容器宽度,默认会自动缩小项目,不会另起一行。
  4. 项目在交叉轴上如果没有设置高度,会被拉伸填满容器。如果容器也没有设置高度,最高的项目高度则为容器高度。



三、轴线

  1. flex轴线:两根轴线,主轴和交叉轴。
  2. 由方向属性 flex-diretion 控制主轴的方向。(默认为row,从左到右)
  3. 主轴:控制项目的排列的方向(上下左右)
  4. 交叉轴:配合主轴实现对齐方式。永远垂直于主轴。

所有的属性都围绕轴线展开,必须理解轴线!(示意图)


四、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;
  1. 设置项目的排列方式。(项目跟着主轴来排列)
  2. 指定主轴的方向
  3. row:默认。横向排列,从左到右。(起点在左)
  4. column :竖向排列,从上到下。(起点在上)
  5. row-reverse :横向排列,从右到左。(起点在右)
  6. column-reverse:竖向排列,从下到上。(起点在下)

(2)flex-wrap

bash 复制代码
flex-wrap:nowrap | wrap | wrap-reverse;
  1. 设置项目换行
  2. 默认情况下,项目都排列在一行(一条轴线上)。不会换行。
  3. nowrap :默认。不换行。
  4. wrap :换行。项目大小超出一行,换到下一行。从上往下排列。
  5. wrap-reverse:前后反转换行。项目大小超出一行,换到下一行。从下往上排列。

(3)flex-flow

bash 复制代码
flex-flow:<flex-direction> <flex-wrap>;
  1. 复合属性。flex-directionflex-wrap 简写。
  2. 默认值: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;
  1. 定义项目在主轴上的对齐方式。
  2. 默认值:justify-content: flex-start;
  3. flex-start:默认值,左对齐。(主轴起始位置对齐,默认方向下是左上角对齐)
  4. flex-end:右对齐。(主轴结束位置对齐,默认方向下是右上角对齐)
  5. center: 居中。(主轴位置居中对齐,默认方向下就是水平居中)
  6. space-between: 两端对齐,项目中间间距相等。(主轴位置上两端对齐,两端无间距)
  7. space-around: 每个项目两侧间距相等,两端有间距,两端间距为项目间距的一半。(主轴位置上两端对齐,两端有间距)
  8. space-evenly: 在弹性空间内均匀的分配间距,容器两端和项目之间的间距相等。(主轴位置上两端对齐,两端有间距,两端间距与项目间距相等)

(5)align-items

bash 复制代码
align-items:stretch | flex-start | flex-end | center | baseline;
  1. 定义项目在交叉轴上的对齐方式。(单行)
  2. 在项目为单行时适用。
  3. stretch: 默认值。项目被拉伸为容器大小,在没有设置项目的固定高度下。(交叉轴的剩余空间)
  4. flex-start:项目沿交叉轴起始位置对齐。(按默认方向就是左上角对齐)
  5. flex-end: 项目沿交叉轴终点位置对齐。(按默认方向就是左下角对齐)
  6. center: 项目在交叉轴方向居中对齐。(按默认方向就是垂直居中)
  7. baseline: 项目在交叉轴方向沿项目第一行文字基线对齐。

(* strech案例应该为:所有块都充满屏幕,此处设置了固定高度,如下图)


(6)align-content

bash 复制代码
align-content:stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;
  1. 定义多行项目(多根主轴线)对齐方式。(常在产生换行时使用)
  2. 类似 justify-content,不过 justify-content 控制的是项目与项目之间的空间分配, align-content 控制的是行与行之间的空间分配(我理解的就是主轴线的排列对齐方式)
  3. stretch: 默认值。交叉轴上的每一个轴线被平均分配高度。轴线上的项目被拉伸适应于该轴线,在没有设置项目的固定高度下。
  4. flex-start: 所有行在交叉轴方向上,沿交叉轴起始位置对齐。(按默认方向就是所有行从上往下,从左到右依次排列。左上角)
  5. flex-end: 所有行在交叉轴方向上,沿交叉轴结束位置对齐。(按默认方向就是所有行以左下角为起点,从上往下,从左到右依次排列)
  6. center: 所有行在交叉轴方向上,居中对齐。(按默认方向就是所有行垂直居中于交叉轴上)
  7. space-between: 所有行在交叉轴方向上两端对齐,两端无间距,中间间隔相等。(按默认方向就是在交叉轴上垂直的两端对齐)
  8. space-around: 所有行在交叉轴方向上两端对齐,两端和行之间都有间距,两端的间距是行间距一半。(按默认方向就是在交叉轴上垂直的排列。)
  9. space-evenly: 所有行在交叉轴方向上两端对齐,两端和行之间都有间距,所有间距相等。(按默认方向就是在交叉轴上垂直排列,两端与行间距一致)

(7)flex-grow

bash 复制代码
flex-grow:<number [0,∞]>;
  1. 定义flex项目增长因子【定义项目在主轴方向上的放大比例,默认为0。(不放大)】
  2. 当主轴(父元素)还有剩余空间时,如何分配这些空间。
  3. 该属性规定了在容器中分配剩余空间的相对比例。剩余空间是flex容器大小减去所有flex项目大小加起来的大小。
  4. 项目的grow系数一样,所有项目将剩余空间按相同比例分配。
  5. 通常与flex-shrinkflex-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,∞]>;

  1. 定义flex项目收缩因子(收缩规则),默认为1(收缩)。不可为负值。
  2. 默认为1: 即如果空间不足,该项目将缩小。
  3. 在项目宽度之和大于容器时才会发生收缩,收缩大小依据 flex-shrink 值。
  4. 当剩余空间不够时让各个子元素收缩以适应有限空间
  5. 该属性处理浏览器在计算弹性元素的 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;
  1. 定义项目的初始化尺寸(基准值),默认为 auto。(项目未定义大小,会解析为内容大小。项目定义了200px宽度,auto值就为200px)
  2. flex布局中,flex-basis 优先级高于 width。(同时设置flex-basis值与width值,生效的时flex-basis值)
  3. flex-basis 值不是 auto 时,width 属性会被忽略。
  4. flex-basis 值为 auto 或者 0 时,元素的大小由自身内容决定。
    auto: 尺寸为最大内容宽度;0:尺寸为最小内容宽度。
  5. 设置了basis值,元素在增长时:可以同其他元素一样扩张,初始值和最小值为设置的basis值。 元素在收缩时:可以同其他元素一样收缩,初始值和最大值为设置的basis值。
  6. 这里有一个疑问,也没有找到很详细的说明,有知道的吗,请分享。flex-basis:auto,flex-basis:0;异同和具体计算原理和尺寸说明。

flex-basis:auto;

在设置了元素宽度的前提下,使用flex-basis:auto, auto取值为设置的宽度值。


flex-basis:0;

  1. 以元素内容为基准,折叠到最小可能的宽度。
  2. 元素设置的宽度会失效,取值为 flex-basis:0,也就是元素内容最小宽度

(10) flex

bash 复制代码
flex: <flex-grow> [<flex-shrink>] [<flex-basis>];
  1. 复合属性,flex-growflex-shrinkflex-basis的简写,默认为 0 1 auto。
  2. 后面两个参数为可选参数
  3. 定义项目分配剩余空间,用flex表示项目占多少份数

1. 关键字简写

  1. flex: initial; 等同于 flex:0 1 auto; 也就是默认值。不拉伸,可收缩,宽度为内容宽度。
  2. flex: auto; 等同于 flex: 1 1 auto; 可拉伸,可收缩,宽度为内容宽度。
  3. flex: none: 等同于 flex:0 0 auto; 不拉伸,不收缩,宽度为内容宽度。
  4. flex:<number>; flex:2; 等同于 flex: 2 1 0;

2. 多种简写方式

  1. 根据值的类型判断赋值的属性
  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-growflex-shrink

bash 复制代码
flex:1 0;     // flex: 1 0 0%;

带单位的两个值为设置: flex-growflex-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;
  1. 单个项目在交叉轴上的对齐方式,默认为 auto
  2. 优先级高于 align-items; align-items 是控制所有项目交叉轴对齐方式。
  3. 属性值与 align-items 取值一致,多一个:auto;
  4. 没有文化的比喻就是做人群中最靓的仔。

例1. 项目上设置align-self

  1. 容器上设置交叉轴对齐方式为:align-items: flex-start;
  2. 项目2单独设置: align-self:center;

(12) order

bash 复制代码
order:<number>;
  1. 定义项目在主轴上的排列顺序(前后顺序)。
  2. 默认值:0。
  3. 可以取负值。

例: 项目2设置为-1,使其排列在首位


五、flex习题

答案在"参考链接": [CSS flex属性深入理解]


参考链接:

  1. 也许你并不知道 flex-shrink 的计算机制
  2. CSS flex属性深入理解
  3. flex布局教程
相关推荐
be or not to be2 小时前
CSS 背景(background)系列属性
前端·css·css3
冴羽2 小时前
CSS 新特性!瀑布流布局的终极解决方案
前端·javascript·css
牛奶皮子3 小时前
合并 CSS 文件可以减少 HTTP 请求数,因为每个请求都会带来额外的网络开销
css·网络·http
幻影星空VR元宇宙10 小时前
9D裸眼轨道影院投资多少钱与5D动感影院设备的市场潜力分析
css·百慕大冒险·幻影星空
proud121212 小时前
使用thymeleaf生成PDF方案
javascript·css·pdf
霍理迪14 小时前
CSS——背景样式以及雪碧图、渐变
前端·css
wordbaby1 天前
Flexbox 布局中的滚动失效问题:为什么需要 `min-h-0`?
前端·css
前端小黑屋1 天前
查看 Base64 编码的字体包对应的字符集
前端·css·字体
hqwest1 天前
码上通QT实战04--主窗体布局
开发语言·css·qt·布局·widget·layout·label
狗哥哥1 天前
企业级 Vue3 + Element Plus 主题定制架构:从“能用”到“好用”的进阶之路
前端·css·架构