flex-space-algorithm

flex-basis、flex-grow、flex-shrink

  • flex-basis、flex-grow、flex-shrink这三个属性决定了flex item的展示尺寸
  • 要想了解三者是如何决定flex item的尺寸前,先要了解一下max-contentmin-content正负向自由空间概念
  • 注意以下的讨论都是在主轴为横轴基础上讨论的

min-content、max-content

  • 这两个都是用来设置width
  • 通过下面的例子,我们就知道他们是什么含义
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
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .wp {
        width: 400px;
        border: 1px solid red;
      }
      .box {
        border: 1px dotted blue;
      }
      .box1 {
        width: min-content;
      }
      .box2 {
        width: max-content;
      }
    </style>
  </head>
  <body>
    <div class="wp">
      <p class="box box1">
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Officia
        voluptatibus quos nihil dolores
      </p>
      <p class="box box2">
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Officia
        voluptatibus quos nihil dolores
      </p>
    </div>
  </body>
</html>
  • mix-max-contet.png
    • mix-max-content.png
  • 可以看到box1width设置了min-content后,它抓住了一切机会来换行,直到出现一个最大的无法换行的单词才停止,就如截图中的voluptatibus单词
    • 也就是说min-content的宽度是由最长不可换行单词决定的
  • 而设置了max-contetbox2却有截然相反的表现,它尽可能的不换行,就跟我们设置了white-space:no-wrap;的表现很类似,即使外层.wp设置了固定尺寸,它也会冲破限制,溢出了
    • max-content确定的宽度是内容正常展示时最大宽度
  • min-contentmax-contentflex布局中有关键作用,下面会做讲解

正负向自由空间

正向自由空间 positive free space

  • 正向自由空间描述的是flex布局时,flex container剩余的空间
  • positive-free-space.png
    • positive-free-space.png
  • flex布局中,当flex container宽为500px,内部有三个100px初始宽度的flex item,那么剩下的200px就是正向自由空间,这200px的宽度后续将交给flex-grow按照一定的策略来分配

负向自由空间 negative free space

  • 负向自由空间其实是一个和正向类似的概念
  • 它描述的是所有flex item宽度和超出flex container的部分
  • negative-free-space.png
    • negative-free-space.png
  • flex container仍然是500px,但三个flex item初始宽度变为200px了,他们宽度总和超出flex container 100px,这个100px就为负向自由空间,这100px的宽度后续将交给flex-shrink按照一定策略来缩减(消化),让其三者宽度总和不超过500px

注意

  • 正负向自由空间都是flex-growflex-shrink参与空间分配前的概念,当这两个属性参与空间分配后,其实这个空间就可以视为不存在了

flex-basis

  • flex-basisflex布局的基础
  • flex-basis决定了flex item在主轴上的初始尺寸
    • 初始尺寸用来计算正、负向空间
    • 正、负空间决定了flex-growflex-shrink哪个生效

取值

  • auto
    • 默认值
    • 如果设置了width,则使用width值做为初始尺寸,否则使用max-content(最大内容宽度)做为初始尺寸
  • content
    • 不管有没有设置width,都使用我的max-content(最大内容宽度)做为初始尺寸
    • 存在兼容问题
    • flex-basis-content.png
      • flex-basis-content.png
  • 非0数值
    • 10px
    • 10%
    • 10em
    • 将对应数值的计算值做初始尺寸
  • 0
    • 初始尺寸为 0,代表当前flex item不参与正、负空间计算

例子

  • 由于content存在兼容问题,所以没举content的例子
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .wp {
        width: 400px;
        border: 1px solid red;
        display: flex;
        flex-direction: row;
      }
      .box {
        border: 1px dotted blue;
        /* 为了保持一致,让flex item 尺寸不放大也不缩小,就用初始尺寸 */
        flex-grow: 0;
        flex-shrink: 0;
      }

.box+.box{
margin-left:10px;
}

      .box:nth-child(1) {
        /* 未设置width,所以使用max-content */
        flex-basis: auto;
      }

      .box:nth-child(2) {
        /* auto,并width有值,则取width对应值 */
        flex-basis: auto;
        width: 40px;
      }

      .box:nth-child(3) {
        /* 20px  */
        flex-basis: 20px;
      }

      .box:nth-child(4) {
        /* 30% */
        flex-basis: 30%;
      }

      .box:nth-child(5) {
        /* 0 */
        /* 最后宽度为min-content */
        flex-basis: 0;
      }

    </style>
  </head>
  <body>
    <div class="wp">
      <p class="box">1 123</p>
      <p class="box">22</p>
      <p class="box">333 3</p>
      <p class="box">4444</p>
      <p class="box">55555 11</p>
    </div>
  </body>
</html>
  • 第一个盒子
    • example-1.png
      • example-1.png
    • flex-basisauto,又没设置width,所以最终尺寸为max-content
  • 第二个盒子
    • example-2.png
      • example-2.png
    • 设置auto又设置了width,所以取width宽度40px
      • 注意这里虽然min-content>width,但是最终尺寸仍然是width:40px(导致产生溢出)
      • 所以当flex-basis指定auto同时又设置width时,最终尺寸将不受min-content影响
  • 第三个盒子
    • example-3.png
      • example-3.png
    • 虽然设置了flex-basis:20px;,但由于min-content30px,所以最终的大小为30px
  • 第四个盒子
    • example-4.png
      • example-4.png
    • 30%120px,而且min-content<120px,所以最终尺寸为120px
  • 第五个盒子
    • example-5.png
      • example-5.png
    • flex-basis0,不参与空间计算,所以最终尺寸为min-content

width、flex-basis、min-width、max-width 关系

  • 记住公式
  • 优先级flex-basis>width>min|max-content
    • 最终展示的大小会受max|min-width限制
    • 同时设置上述属性并且flex-basis不为auto
      • flex-basis会覆盖(忽略)width值进行布局,flex-item最终展现的尺寸会受min|max-width限制
  • 具体可看下面例子
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
41
42
43
44
45
46
47
48
49
50
51
52
53

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .wp {
        border: 1px solid red;
        display: flex;
        flex-direction: row;
      }
      .box {
        border: 1px dotted blue;
        flex-grow: 0;
        flex-shrink: 0;
      }
      .box + .box {
        margin-left: 10px;
      }
      .box:nth-child(1) {
        flex-basis: auto;
        /* flex-basis为auto,所以取width为初始尺寸 */
        width: 200px;
        /* 最终展示受max-width限制 */
        max-width: 100px;
      }
      .box:nth-child(2) {
        flex-basis: 200px;
        /* flex-basis非auto,所以width被忽略 */
        width: 400px;
      }
      .box:nth-child(3) {
        flex-basis: 200px;
        /* flex-basis非auto,所以width被忽略 */
        width: 400px;
        /* 最终展示受max-width限制 */
        max-width: 100px;
      }
    </style>
  </head>
  <body>
    <div class="wp">
      <p class="box">1 123 zcjviodf ajdiof jaoisdf asdjifo</p>
      <p class="box">1 123 zcjviodf ajdiof jaoisdf asdjifo</p>
      <p class="box">1 123 zcjviodf ajdiof jaoisdf asdjifo</p>
    </div>
  </body>
</html>
  • 第一个盒子
    • space-1.png
      • space-1.png
    • flex-basisauto,所以width:200px生效,但最终的展示大小受max-width:100px限制,所以最终100px
  • 第二个盒子
    • space-2.png
      • space-2.png
    • flex-basis不为auto,所以width直接被忽略,所以最终尺寸为flex-basis指定的200px
  • 第三个盒子
    • space-3.png
      • space-3.png
    • flex-basis不为auto,所以width被忽略,展示尺寸为flex-basis指定的200px,最终的尺寸受max-width:100px限制,所以最后为100px

flex-basis 和 box-sizing

  • 注意flex-basis会受box-sizing影响
    • flex-basis指定的尺寸,其实是box-sizing设置的盒子尺寸
  • 例子
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
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .wp {
        display: flex;
      }
      .box {
        flex-basis: 100px;
        border: 10px solid red;
        padding: 20px;
      }
      .box + .box {
        margin-left: 10px;
      }
      .box:nth-child(1) {
        box-sizing: border-box;
        /* flex-basis指定的是border-box的尺寸 */
      }
      .box:nth-child(2) {
        /* flex-basis指定的是content-box的尺寸 */
        box-sizing: content-box;
      }
    </style>
  </head>
  <body>
    <div class="wp">
      <div class="box">1</div>
      <div class="box">2</div>
    </div>
  </body>
</html>
  • 可以看到同样的paddingborder最后得出的尺寸不一样
  • 第一个盒子
    • flex-basis指定的是border-box的尺寸
    • box-sizing-1.png
      • box-sizing-1.png
  • 第二个盒子
    • flex-basis指定的是content-box的尺寸
    • box-sizing-2.png
      • box-sizing-2.png

小结

  • flex-basis决定了flex-item的初始尺寸
  • flex-basis设置的是box-sizing指定的盒子尺寸
  • 而初始尺寸又决定了正负向空间,进而影响flex-growflex-shrink的表现
  • flex-basisauto时,取width值为初始尺寸
  • 否则用flex-basis指定的值做为初始尺寸
  • 最终展示的尺寸会受min|max-width限制

flex-grow

  • 正向空间的分配
    • 存在正向空间时,则需要将空间按策略分配给每个flex-item
    • 也就是按照一个放大策略将剩余空间分配给每个flex-item
    • 决定如何放大的关键属性就是flex-grow
  • 默认值为0,即不放大

放大算法

  • flex-grow只能取正值
  • 它代表的是一个拉伸(放大)因子
    • 可以理解为一个比例(权重),代表有多少正向空间的分配权利
  • 算法公式
    • 最终尺寸=初始尺寸 + 分配比例*正向空间大小
    • 分配比例 = 当前flex-item的拉伸因子/所有flex-item的拉伸因子之和
      • 注意
        • 所有flex-item的拉伸因子之和 最小值为 1,即如果拉伸因子之和小于 1,也会取 1 参与计算
        • 这会导致出现正向空间没有被全部分配的场景,具体见第二个例子
    • 比如正向空间为 x,三个元素的 flex-grow 分别为 a,b,c。设 sum 为 a + b + c。那么三个元素将得到的正向空间分别是 x * a / sum, x * b / sum, x * c / sum,最终尺寸为初始尺寸加上+获得的正向空间

例子 1,拉伸因子之和>=1

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
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .c-Wp {
        width: 500px;
        border: 1px solid red;
        display: flex;
      }
      .c-Box {
        outline: 1px dotted blue;
        /* 不缩放 */
        flex-shrink: 0;
      }
      .c-Box:nth-child(1) {
        /* 正向空间我分配 1/6 */
        flex-grow: 1;
        flex-basis: 100px;
      }
      .c-Box:nth-child(2) {
        /* 正向空间我分配 2/6 */
        flex-grow: 2;
        flex-basis: 150px;
      }
      .c-Box:nth-child(3) {
        /* 正向空间我分配 3/6 */
        flex-grow: 3;
        flex-basis: 100px;
      }
    </style>
  </head>
  <body>
    <div class="c-Wp">
      <div class="c-Box">one jiojio</div>
      <div class="c-Box">two jlkzjclkvz</div>
      <div class="c-Box">three cjioajdisof</div>
    </div>
  </body>
</html>
  • 可以看到flex container尺寸为500px
  • 三个flex item的初始尺寸分别为100px150px100px,所以剩余500-350=150的正向空间
  • 三个flex item分别设置了1、2、3的拉伸因子(权重)
  • 我们记sum=1 + 2 + 3 = 6为权重总和,所以每个flex-item的分配比例也就可以计算出来
  • 第一个盒子
    • 1/sum1/6,即150 * 1/6 = 25
    • 所以最终尺寸为100(初始尺寸) + 25(正向空间)=125
    • grow-over-1.png
      • grow-over-1.png
  • 第二个盒子
    • 2/sum2/6,即150 * 1/6 = 50
    • 所以最终尺寸为150(初始尺寸) + 50(正向空间)=200
    • grow-over-2.png
      • grow-over-2.png
  • 第一个盒子
    • 3/sum3/6,即150 * 1/6 = 75
    • 所以最终尺寸为100(初始尺寸) + 75(正向空间)=175
    • grow-over-3.png
      • grow-over-3.png

例子 2,拉伸因子之和<1

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
41
42
43
44
45
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .c-Wp {
        width: 500px;
        border: 1px solid red;
        display: flex;
      }
      .c-Box {
        outline: 1px dotted blue;
        /* 不缩放 */
        flex-shrink: 0;
      }
      .c-Box:nth-child(1) {
        /* 正向空间我分配 0.1/1 */
        flex-grow: 0.1;
        flex-basis: 100px;
      }
      .c-Box:nth-child(2) {
        /* 正向空间我分配 0.2/1 */
        flex-grow: 0.2;
        flex-basis: 150px;
      }
      .c-Box:nth-child(3) {
        /* 正向空间我分配 0.3/1 */
        flex-grow: 0.3;
        flex-basis: 100px;
      }
    </style>
  </head>
  <body>
    <div class="c-Wp">
      <div class="c-Box">one jiojio</div>
      <div class="c-Box">two jlkzjclkvz</div>
      <div class="c-Box">three cjioajdisof</div>
    </div>
  </body>
</html>
  • 可以看到sum= 0.1 + 0.2 + 0.3 = 0.6 < 1,所以最终取1参与计算
  • 第一个盒子
    • 最终尺寸:100(初始尺寸) +0.1/1 * 150 = 115
    • grow-less-1.png
      • grow-less-1.png
  • 第二个盒子
    • 最终尺寸:150(初始尺寸) +0.2/1 * 150 = 180
    • grow-less-2.png
      • grow-less-2.png
  • 第三个盒子
    • 最终尺寸:100(初始尺寸) +0.3/1 * 150 = 145
    • grow-less-3.png
      • grow-less-3.png
  • 可以看到最后还有500 -115 - 180 - 145 = 60的尺寸没有分配

等分布局

  • 如何实现自适应等分布局?
    • 所有flex itemflex-basis设置为0flex-grow设置为相同值(总和>1)即可
  • 原理
    • flex-basis:0代表初始尺寸为 0,当所有flex item的初始尺寸都为 0,那计算出来的正向空间就为flex container的尺寸
    • flex-grow设置为相同值并且总和>1,代表平均分配所有正向空间,由于初始尺寸为 0,所有flex item得到的正向空间又相同,所以就实现了等分布局
  • 例子
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
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .c-Wp {
        width: 500px;
        border: 1px solid red;
        display: flex;
      }
      .c-Box {
        outline: 1px dotted blue;
        /* 不缩放 */
        flex-shrink: 0;

        flex-basis: 0;
        flex-grow: 1;
      }
    </style>
  </head>
  <body>
    <div class="c-Wp">
      <div class="c-Box">one jiojio</div>
      <div class="c-Box">two jlkzjclkvz</div>
      <div class="c-Box">three cjioajdisof</div>
    </div>
  </body>
</html>
  • average.png
    • average.png

flex-shrink

  • 负向空间的分配
    • 存在负向空间时,需要按照缩小算法收缩每个flex-item
  • 默认值为0,即不缩小

缩小算法

  • 和放大算法不同,缩小算法在计算每个flex item的收缩大小时,不仅需要考虑收缩因子(flex-shrink指定的值),还需要考虑item的初始尺寸
  • 具体算法
    • 总权重 TW = 每个(itemflex-shrink * item的初始尺寸)之和
    • 当前item需要缩小的尺寸= 负向空间 _ ((当前 item 的flex-shrink _ 初始尺寸) / 总权重 TW)
    • 最终尺寸 = 当前item初始尺寸 + 需要缩小尺寸 (因为负向空间尺寸为负值,所以此处为加号)

例子 1,缩小因子之和>=1

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
41
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .c-Wp {
        width: 500px;
        border: 1px solid red;
        display: flex;
      }
      .c-Box {
        outline: 1px dotted blue;
        flex-grow: 0;
      }
      .c-Box:nth-child(1) {
        flex-shrink: 1;
        flex-basis: 150px;
      }
      .c-Box:nth-child(2) {
        flex-shrink: 2;
        flex-basis: 200px;
      }
      .c-Box:nth-child(3) {
        flex-shrink: 3;
        flex-basis: 300px;
      }
    </style>
  </head>
  <body>
    <div class="c-Wp">
      <div class="c-Box">1</div>
      <div class="c-Box">2</div>
      <div class="c-Box">3</div>
    </div>
  </body>
</html>
  • 负向空间 = 500 - 150 - 200 - 300 = -150
  • 计算总权重 TW = 1 * 150 + 2 * 200 + 3 * 300 = 1450
  • 第一个盒子
    • 最终尺寸= 150 + (-150负向空间 * ((1*150) / 1450)) = 134.5
    • shrink-over-1.png
      • shrink-over-1.png
  • 第二个盒子
    • 最终尺寸= 200 + (-150负向空间 * ((2*200) / 1450)) = 158.6
    • shrink-over-2.png
      • shrink-over-2.png
  • 第三个盒子
    • 最终尺寸= 300 + (-150负向空间 * ((3*300) / 1450)) = 206.9
    • shrink-over-3.png
      • shrink-over-3.png

例子 2,缩小因子之和<1

  • 当缩放因子之和<1 时,只有缩放因子之和* 负向空间的空间会参与收缩
    • 例如 , 缩放因子分别为0.1、0.2、0.3,总和<1,负向空间的尺寸为 150,那么只有 90 的空间会被缩小
  • 例子(将例子 1 的缩放因子设置为缩小十倍)
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
41
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        box-sizing: border-box;
      }
      .c-Wp {
        width: 500px;
        border: 1px solid red;
        display: flex;
      }
      .c-Box {
        outline: 1px dotted blue;
        flex-grow: 0;
      }
      .c-Box:nth-child(1) {
        flex-shrink: 0.1;
        flex-basis: 150px;
      }
      .c-Box:nth-child(2) {
        flex-shrink: 0.2;
        flex-basis: 200px;
      }
      .c-Box:nth-child(3) {
        flex-shrink: 0.3;
        flex-basis: 300px;
      }
    </style>
  </head>
  <body>
    <div class="c-Wp">
      <div class="c-Box">1</div>
      <div class="c-Box">2</div>
      <div class="c-Box">3</div>
    </div>
  </body>
</html>
  • 负向空间 = 500 - 150 - 200 - 300 = -150
  • 计算总权重 TW = 0.1* 150 + 0.2 * 200 + 0.3 * 300 = 145
  • 第一个盒子
    • 最终尺寸= 150 + (-150负向空间 * (0.1 + 0.2 + 0.3) * ((0.1*150) / 145)) = 140.69
    • shrink-less-1.png
      • shrink-less-1.png
  • 第二个盒子
    • 最终尺寸= 200 + (-150负向空间 * (0.1 + 0.2 + 0.3) * ((0.2*200) / 145)) = 175.17
    • shrink-less-2.png
      • shrink-less-2.png
  • 第三个盒子
    • 最终尺寸= 300 + (-150负向空间 * (0.1 + 0.2 + 0.3) * ((0.3*300) / 145)) = 244.14
    • shrink-less-3.png
      • shrink-less-3.png
  • 可以看到还有60px溢出了(没有被收缩)

小结

  • 放大和缩小的算法不太一样,缩小算法需要考虑初始尺寸
  • 总结公式如下
  • sumary.png
    • sumary.png

简写属性

flex

  • flex是上述三者的简写
    • 其默认值为flex: 0 1 auto;
    • 三个值依次代表flex-growflex-shrinkflex-basis
    • 0 代表不放大
    • 1 代表不缩小
    • auto 代表使用 width 值做为初始尺寸
  • 由于默认值为0 1 auto,所以在某些特定场景,会出现问题,所以建议在任何场景都显示指明flex的三个属性值

常用缩写

  • flex:1
    • 等同flex: 1 1 0;
  • flex:0
    • 等同flex: 0 1 0;
  • flex:auto
    • 等同flex: 1 1 auto;

flex 应用

移动端常见,头尾固定,中间局部滚动布局

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
41
42
43
44
45
46
47
48
49
50
51
52
53
<template>
  <div class="c-BaseLayoutVertical">
    <div
      v-if="this.$slots.header"
      class="c-BaseLayoutVertical-hd"
    >
      <slot name="header" />
    </div>
    <div class="c-BaseLayoutVertical-bd">
      <slot />
    </div>
    <div
      v-if="this.$slots.footer"
      class="c-BaseLayoutVertical-ft"
    >
      <slot name="footer" />
    </div>
  </div>
</template>
<script>
/**
 * * 常见垂直上中下三行布局
 */
export default {
  name: 'BaseLayoutVertical'
}
</script>
<style scoped>
/**
 * ! c-BaseLayoutVertical节点的父节点需要有高度
 */
.c-BaseLayoutVertical {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.c-BaseLayoutVertical-hd {
  flex: 0 0 auto;
}
.c-BaseLayoutVertical-bd {
  flex: 1 1 auto;
  height: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  /* 优化滚动性能 */
  will-change: scroll-position;
  position: relative;
  z-index: 1;
}
.c-BaseLayoutVertical-ft {
  flex: 0 0 auto;
}
</style>

总结

确定 flex item 尺寸的步骤

  • 首先确定初始尺寸
    • flex-basis、width决定
      • flex-basis为auto时,取width值,若未显示指定width值,则取max-content
      • auto时,直接取对应值的计算值为初始尺寸
  • 确定空间类型
    • 初始尺寸之和 >flex container尺寸时存在负向空间
      • 负向空间大小 = 初始尺寸之和 - flex container尺寸
    • 初始尺寸之和 < flex container尺寸时存在正向空间
      • 正向空间大小 = flex container尺寸 - 初始尺寸之和
  • 根据空间类型决定使用flex-growflex-shrink策略来分配空间,得到展示大小
    • 正向空间直接按拉伸因子(flex-grow申明的)所占比例来分配
    • 负向空间收缩不光要考虑收缩因子,还需要考虑到初始尺寸
  • 展示大小受min|max-width|height的限制

参考