Published on

你确定掌握了 flex 吗?

flex基础见阮一峰大佬的博客:Flex 布局教程:语法篇,本文着重讲解两三点细节,敬请食用。

align-items 和 align-content

  • align-items 针对单行,大白话容器内的每一个子项都按照设定对齐
  • align-content 针对多行,大白话容器内的所有子项看成一个整体按照设定对齐

flex 计算

了解 flex 分配空间的逻辑,对于前端开发来说是比较重要的。

/* grow  shrink basis */
/* 1       1      0 */
flex: 1;
/* 1       1    auto */
flex: auto;
/* 0       0    auto */
flex: none;

与计算密切相关的属性是 flex-basis,在计算中,它表示分配空间之前,占据主轴的空间大小。 auto 表示元素本身的大小,数字/百分比 则会忽略自身的大小按照设置的值来确定分配空间。

计算过程:

  1. 得到剩余空间 = 总空间 - 确定的空间
  2. 得到需要分配的数量 = flex-grow 为 1 的盒子数量
  3. 得到单位空间大小 = 剩余空间 / 分配数量
  4. 得到各个元素分配的大小 = 单位空间 * 分配数量 + 原来的长度
<style>
   .box {
       display: flex;
       width: 600px;
       height: 100px;
       background-color: yellowgreen;
   }

   .item-1 {
       width: 100px;
       background-color: yellow;
   }
   .item-2 {
       width: 200px;
       flex-basis: 300px; /* 不为 auto 则覆盖 width */
       background-color: palegoldenrod;
   }
   .item-3 {
       flex: 1;
   }
</style>
<div class="box">
    <div class="item-1"></div>
    <div class="item-2"></div>
    <div class="item-3"></div>
</div>

过程如下:

rest = 600 - 100 - 300 - 0 = 300
flex_grow_count = 1
unit = rest / flex_grow_count
assign_size = unit * 1 + 0

所以当只有 flex: 1 一个flex-grow时,表现为占据剩下的所有空间。

如果是下面这样的呢?

.item-1 {
    flex: 2 1 10%; /*注意 flex-grow 为 2*/
}
.item-2 {
    flex: 1 1 10%;
}
.item-3 {
    width: 100px;
    flex: 1 1 200px;
}

过程如下:

rest = 600 - 600 * 0.1 - 600 * 0.1 - 200 = 280
flex_grow_count = 2 + 1 + 1 = 4
unit = rest / flex_grow_count = 70
item1: 600 * 0.1 + 2 * 70 = 200
item2: 600 * 0.1 + 1 * 70 = 130
item3: 200 + 70 270

理解上面2个例子,基本的分配空间逻辑就清楚了,可以继续了解空间不足时shrink的计算逻辑,这篇文章写的比较详细:你不知道的 flex-shrink 计算规则

flex: 1 滚动条不生效

当发生 flex 嵌套,多个 flex:1 时,会产生 flex:1 内的元素滚动失效,这是因为被嵌套在 flex 内部的元素默认设定了 min-height: auto,它会将元素的最小高度设置为其内容的自然高度,直接影响flex的空间计算,从而导致了滚动无效,比如下例中的 content 会被内部元素撑开,因此需要设定 min-height: 0 来解决即可。(注意,多层flex嵌套,则每一层都需要设置哦)

<style>
   .container {
       display: flex;
       width: 500px;
       height: 90vh;
       flex-direction: column;
       background-color: yellowgreen;
   }

   .head {
       height: 20px;
       background-color: black;
   }

   .content {
       display: flex;
       flex-direction: column;
       flex: 1;
       /* 关键代码,设置 min-height 为 0 */
       min-height: 0;
   }
   .long-content {
       flex: 1;
       overflow: auto;
   }

   .item {
       height: 200px;
       margin: 20px;
       background-color: pink;
   }
</style>
<div class="container">
    <div class="head"></div>
    <div class="content">
        <!--header or other el-->
        <div class="long-content">
            <div class="item"></div>
            <div class="item"></div>
            <div class="item"></div>
            <div class="item"></div>
            <div class="item"></div>
            <div class="item"></div>
            <div class="item"></div>
        </div>
    </div>
</div>

上下文影响

  1. flex 会让元素变成 BFC
  2. 会让具有 z-index 且值不为 auto 的子元素成为 SC

justify-content: center 最后一行的对齐问题

参考张鑫旭大佬的文章 -- 让 CSS flex 布局最后一行列表左对齐的 N 种方法