Skip to content

Flex 语法和计算规则 #23

@maomao1996

Description

@maomao1996

Flex 语法和计算规则

flex 是以下三个 CSS 属性的简写

  • flex-grow 设置 flex 元素的增长系数;负值无效,省略时默认值为 1 (初始值为 0)
  • flex-shrink 设置 flex 元素的收缩系数(仅在默认 width/height 之和大于容器时生效);负值无效,省略时默认值为 1 (初始值为 1)
  • flex-basis 设置 flex 元素在主轴方向上的初始大小;省略时默认值为 0 (初始值为 auto)

语法

单值语法

/* 全局属性值 */
/* 初始值 */
flex: initial; => flex: 0 1 auto
/* 从其父级继承 (flex 属性不可被继承,将设置为初始值) */
flex: inherit; => flex: 0 1 auto
/* 是关键字 initial 和 inherit 的组合(当属性可继承时为 inherit 不可继承时为 initial) */
flex: unset; => flex: 0 1 auto


/* 关键字值 */
/* 根据自身的宽度与高度来确定尺寸 弹性 */
flex: auto; => flex: 1 1 auto
/* 根据自身宽高来设置尺寸 非弹性 */
flex: none; => flex: 0 0 auto


/* 无单位数: flex-grow */
flex: 2; => 2 1 0

/* 一个有效的 width/height 值: flex-basis */
flex: 10px; => 1 1 10px
flex: 20em; => 1 1 20em
flex: min-content; => 1 1 min-content

双值语法

  1. 第一个值必须为一个无单位数
  2. 第二个值必须为以下之一
    1. 无单位数: 当作 flex-shrink
    2. 有效的 width/height 值: 当作 flex-basis
/* 无单位数: flex-grow | flex-shrink */
flex: 2 2; => 2 2 0

/* 有效的 width/height 值: flex-grow | flex-basis */
flex: 2 30px; => 2 1 30px

三值语法

  1. 第一个值必须为一个无单位数,当作 flex-grow
  2. 第二个值必须为一个无单位数,当作 flex-shrink
  3. 第三个值必须为一个有效的 width/height 值,当作 flex-basis
flex: 2 2 10%;

小测试

以下小测试均计算 width

flex 元素宽度之和小于容器

flex-grow 总和大于 1

<style>
  * {
    margin: 0;
    padding: 0;
  }
  .box {
    display: flex;
    margin: 50px;
    width: 1000px;
    height: 300px;
  }
  .left {
    flex: 1 3 200px;
    background: #95b8d1;
  }
  .center {
    flex: 2 2 300px;
    background: #dda789;
  }
  .right {
    flex: 3 1 400px;
    background: #c3d899;
  }
</style>
<div class="box">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>
解答

分析代码可以得出,我们需要计算 flex 元素的增长系数 flex-grow

  1. 计算 flex 元素宽度总和: 200 + 300 + 400 = 900px
  2. 计算剩余容器宽度: 1000 - 900 = 100px
  3. 计算 flex-grow 系数总和: 1 + 2 + 3 = 6
  4. 计算 flex 元素实际宽度(width + 剩余空间)
    1. left: 200 + 100 / 6 * 1 = 216.67px
    2. center: 300 + 100 / 6 * 2 = 333.33px
    3. right: 400 + 100 / 6 * 3 = 450px

CodeSandbox: flex-grow 总和大于 1

flex-grow 总和小于 1

<style>
  * {
    margin: 0;
    padding: 0;
  }
  .box {
    display: flex;
    margin: 50px;
    width: 1000px;
    height: 300px;
    background: #666;
  }
  .left {
    flex: 0.1 3 200px;
    background: #95b8d1;
  }
  .center {
    flex: 0.2 2 300px;
    background: #dda789;
  }
  .right {
    flex: 0.3 1 400px;
    background: #c3d899;
  }
</style>
<div class="box">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>
解答

分析代码可以得出,我们需要计算 flex 元素的增长系数 flex-grow

  1. 计算 flex 元素宽度总和: 200 + 300 + 400 = 900px
  2. 计算剩余容器宽度: 1000 - 900 = 100px
  3. 计算 flex-grow 系数总和: 0.1 + 0.2 + 0.3 = 0.6
  4. 计算 flex 元素实际宽度(width + 剩余空间)
    1. left: 200 + 100 / 1 * 0.1 = 210px
    2. center: 300 + 100 / 1 * 0.2 = 320px
    3. right: 400 + 100 / 1 * 0.3 = 430px
  5. 最后剩余的 40px 不分配

CodeSandbox: flex-grow 总和小于 1

注意点

  1. flex-grow 系数之和大于 1 时: 各个元素按比例占满剩余空间
  2. flex-grow 系数之和小于 1 时: 剩余空间不会全部分配给各个元素

flex-grow 计算公式

# 当 flex-grow 总和小于 1 时按 1 处理
元素宽度 + 剩余空间 / flex-grow 系数总和 * flex-grow 系数 = 实际宽度

flex 元素宽度之和大于容器

<style>
  * {
    margin: 0;
    padding: 0;
  }
  .box {
    display: flex;
    margin: 50px;
    width: 1000px;
    height: 300px;
  }
  .left {
    flex: 1 3 300px;
    background: #95b8d1;
  }
  .center {
    flex: 2 2 400px;
    background: #dda789;
  }
  .right {
    flex: 3 1 500px;
    background: #c3d899;
  }
</style>
<div class="box">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>

解答

分析代码可以得出,我们需要计算 flex 元素的收缩系数 flex-shrink

  1. 计算 flex 元素宽度总和: 300 + 400 + 500 = 1200px
  2. 计算溢出的宽度: 1200 - 1000 = 200px
  3. 计算总权重: 3 * 300 + 2 * 400 + 1 * 500 = 2200
  4. 计算 flex 元素实际宽度(width - 溢出宽度)
    1. left: 300 - 200 * 3 * 300 / 2200 = 218.19px
    2. center: 400 - 200 * 2 * 400 / 2200 = 327.28px
    3. right: 500 - 200 * 1 * 500 / 2200 = 454.55px

CodeSandbox: flex-shrink

flex-shrink 计算公式

# 总权重计算: 各元素的宽度乘以其 flex-shrink 的总和
元素宽度 - 溢出宽度 * flex-shrink 系数 * 元素宽度 / 总权重 = 实际宽度

相关资料

flex - CSS(层叠样式表)| MDN

详解 flex-grow 与 flex-shrink

flex 布局算法

深入理解 flex 布局以及计算

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions