CSS-flex布局与flex:0 1 auto

67 阅读4分钟

前言

Flex 布局(Flexible Box)已成为现代前端开发的标配。它不仅解决了垂直居中的百年难题,还通过强大的动态伸缩能力适配各种屏幕。本文将带你从容器到项目,深度解析 Flex 的每一个细节。

一、 基本概念

Flex 布局通过设置 display: flex 开启。

  • 容器 (Flex Container) :采用 Flex 布局的元素。
  • 项目 (Flex Item) :容器内部的所有直接子元素。

二、 容器属性 (Container Properties)

容器属性控制项目的排列方向、换行方式及对齐。

1. 排列与换行

  • flex-direction:决定主轴方向。

    • row (默认):水平,左起。
    • row-reverse:水平,右起(项目顺序也会反转)。
    • column:垂直,上起。
  • flex-wrap:一行放不下时如何处理。

    • nowrap (默认):不换行,项目会强制挤压。
    • wrap:正常换行。
  • flex-flow:简写属性,默认 row nowrap

2. 对齐方式

  • justify-content:主轴(水平)对齐。

    • flex-start(默认):左对齐
    • flex-end:右对齐
    • center:水平居中
    • space-between:两端对齐,项目之间间隔相等
    • space-around:每个项目两侧间隔相等
  • align-items:交叉轴(垂直)对齐(单行)。

    • stretch (默认):项目未设高度则撑满。
    • flex-start:交叉轴的起点对齐。
    • flex-end:交叉轴的终点对齐。
    • center:垂直居中
    • baseline:项目第一行文字基线对齐。
  • align-content:多根轴线(多行)的对齐方式。若项目只有一根轴线(即不换行),该属性无效。(目前还未使用过🤷‍)


三、 项目属性:Flex 复合属性详解

这是 Flex 的精髓,由 flex-grow, flex-shrink, flex-basis 组成,默认值为 0 1 auto

1. flex-grow:剩余空间的瓜分者

它是用来分配剩余空间的,就是当子元素元素宽带没有超过父元素宽度时,从而根据flex-grow的值来拉长子元素宽度。

  • 默认 0:即便有剩余空间也不放大。
  • 逻辑:当容器宽度 > 子元素总宽度时,按权重分配剩余空间。
  • 注意:如果所有 flex-grow 总和 < 1,剩余空间不会被占满。

2. flex-shrink:溢出空间的承担者

子元素的宽度之和大于容器的时候才会生效,会根据flex-shrink的值控制子元素收缩比例。

  • 默认 1:当空间不足时,项目等比例收缩。
  • 逻辑:当容器宽度 < 子元素总宽度时生效。设置为 0 则表示不收缩。

3. flex-basis:项目的初始主轴尺寸

它是用来设置flex子元素的宽度,它相比于width,它的优先级更高。

  • 默认 auto:宽度取自 width 属性;若没有设置 width,则由内容撑开。

  • 优先级flex-basis > width

  • 计算细节

    • 它的默认值为auto,当为auto的时候width属性是有效的,如果没有设置width那么宽度就是内容自适应

    • flex-basis的值为0%时,设置了width值

      • 如果内容自适应宽度小于width值的话,width值将无效,宽度将为内容自适应
      • 如果内容自适应宽度大于width值的话,width值将有效,宽度为width值
    • flex-basis的值为0%时,没有设置width值

      • 宽度将为内容自适应
    • flex-basis设置了值,没有设置width值

      • 如果内容自适应宽度小于flex-basis值的话,宽度将为flex-baise值
      • 如果内容自适应宽度大于flex-basis值的话,宽度为自适应宽度
    • flex-basis设置了值,也设置了width值

      • flex-basis的值大于width,元素宽度均为flex-baise值

        • 如果内容自适应宽度小于flex-basis值的话,宽度将为flex-baise
        • 如果内容自适应宽度大于flex-basis值的话,宽度也为flex-baise
      • flex-basis的值小于width:

        • 如果内容自适应宽度小于flex-basis值的话,宽度将为flex-baise

        • 如果内容自适应宽度大于flex-basis值的话

          • 宽度小于width的值,宽度为之自适应宽度
          • 宽度大于width的值,宽度为width值

四、 常用 Flex 简写及其表现

在实际开发中,我们常用这几个简写:

简写方式等价于表现
flex: 11 1 0%等分空间。项目会拉伸占满剩余空间,且由于 basis 为 0%,所有项目公平竞争。
flex: auto1 1 auto自适应拉伸。在项目原始尺寸基础上拉伸,适合双栏布局。
flex: 00 1 0%不拉伸,但可收缩,最终尺寸趋于内容自适应。
flex: none0 0 auto无论空间多大或多小,项目都保持原始尺寸,既不拉伸也不收缩。

五、 实战:三栏布局实现

利用 flex: 1 可以轻松实现左右固定、中间自适应的布局:

<!DOCTYPE html>
<html>
  <body>
    <div class="container">
      <div class="left"></div>
      <div class="main"><div class="content"></div></div>
      <div class="right"></div>
    </div>

    <script></script>
  </body>

  <style>
    html,
    body {
      height: 100vh;
      margin: 0;
      padding: 0;
    }
    .container {
      width: 100%;
      height: 100%;
      overflow: auto;
      display: flex;
    }
    .left,
    .right {
      flex: 0 0 200px;
      background: greenyellow;
      height: 100vh; /* 关键:与容器同高 */
      position: sticky; /* 可选:滚动时粘在顶部 */
      top: 0;
    }
    .main {
      flex: 1;
    }
    .content {
      width: 100%;
      height: 10000px;
    }
  </style>
</html>