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布局教程
相关推荐
Fan_web8 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常8 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
赛男丨木子丿小喵8 小时前
visual studio2022添加新项中没有html和css
css·html·visual studio
太阳花ˉ10 小时前
html+css+js实现step进度条效果
javascript·css·html
懒羊羊大王呀12 小时前
CSS——属性值计算
前端·css
看到请催我学习14 小时前
如何实现两个标签页之间的通信
javascript·css·typescript·node.js·html5
昨天;明天。今天。15 小时前
案例-任务清单
前端·javascript·css
秋殇与星河18 小时前
CSS总结
前端·css
神之王楠18 小时前
如何通过js加载css和html
javascript·css·html
软件开发技术深度爱好者1 天前
用HTML5+CSS+JavaScript庆祝国庆
javascript·css·html5