大厂面试(四):Flex弹性布局从原理到计算

"把一只大象塞进冰箱要分三步:

  1. 打开冰箱门
  2. 放进大象
  3. 关上冰箱门"

相信大家都听过这个经典的问题,但是,当前端遇到两只大象要装进一个冰箱时,你会发现,事情开始变得有趣起来...

本文我们将通过深入解析flex弹性布局,揭开如何在前端页面中解决"大象装冰箱"这个经典难题。


一、Flex核心机制解析

问题1:什么是Flex格式化上下文?

回答:

当元素设置display: flexinline-flex时,其直接子元素自动成为弹性项目 ,这些项目共同构成一个弹性容器。容器内会建立独立的Flex格式化上下文,子元素将遵循弹性布局规则而非常规流布局。

问题2:flex复合属性如何拆解?

回答

举个例子,比如flex: 1 2 500px, 实际上为三个属性的简写:

css 复制代码
flex-grow: 1;    /* 扩展比例 */
flex-shrink: 2;  /* 收缩比例 */
flex-basis: 500px; /* 基础尺寸 */

二、收缩计算(flex-shrink)实战分析

代码案例

html 复制代码
<div class="container">
  <div class="left">左侧</div>
  <div class="right">右侧</div>
</div>

<style>
.container { 
  display: flex; 
  width: 600px; /* 容器宽度 */
}
.left { flex: 1 2 500px; } /* flex-grow:1, shrink:2, basis:500px */
.right { flex: 2 1 400px; } /* flex-grow:2, shrink:1, basis:400px */
</style>

问题3:当子元素总宽度超出容器时如何收缩?

步骤1:计算总溢出空间

  • 子元素基准宽度总和 = flex-basis(left) + flex-basis(right)

    = 500px + 400px

    = 900px

  • 容器宽度 = 600px

  • 溢出空间 = 总基准宽度 - 容器宽度

    = 900px - 600px

    = 300px

步骤2:计算收缩权重

  • 每个元素的收缩权重 = flex-shrink值 × flex-basis值

    • 左元素收缩权重 = 2 × 500px = 1000
    • 右元素收缩权重 = 1 × 400px = 400
  • 总收缩权重 = Σ(所有元素的收缩权重)

    = 1000 + 400

    = 1400

步骤3:计算每个元素的收缩量

收缩量计算公式:

收缩量 = (溢出空间 × 元素收缩权重) / 总收缩权重

  • 左元素收缩量 计算:
    = (300px × 1000) / 1400 ≈ 214.29px (保留两位小数)
  • 右元素收缩量 计算:
    = (300px × 400) / 1400 ≈ 85.71px (保留两位小数)

步骤4:计算最终宽度

  • 左元素最终宽度 = flex-basis值 - 收缩量
    = 500px - 214.29px
    = 285.71px
  • 右元素最终宽度 = flex-basis值 - 收缩量
    = 400px - 85.71px
    = 314.29px

验证计算:

  • 最终总宽度 = 285.71px + 314.29px
    = 600px (等于容器宽度)
  • 总收缩量 = 214.29px + 85.71px
    = 300px (等于溢出空间)

三、扩展计算(flex-grow)实战分析

代码案例

html 复制代码
<style>
.left { flex: 1 2 300px; } /* grow:1, shrink:2, basis:300px */
.right { flex: 2 1 200px; } /* grow:2, shrink:1, basis:200px */
</style>

问题4:当子元素总宽度小于容器时如何扩展?

步骤1:计算总剩余空间

  • 子元素基准宽度总和 = flex-basis(left) + flex-basis(right)

    = 300px + 200px

    = 500px

  • 容器宽度 = 600px

  • 剩余空间 = 容器宽度 - 总基准宽度

    = 600px - 500px

    = 100px

步骤2:计算扩展权重

  • 各元素的扩展权重 = flex-grow值

    • 左元素扩展权重 = 1
    • 右元素扩展权重 = 2
  • 总扩展权重 = Σ(所有元素的flex-grow值)

    = 1 + 2

    = 3

步骤3:计算每个元素的扩展量

扩展量计算公式:

扩展量 = (剩余空间 × 元素flex-grow值) / 总扩展权重

  • 左元素扩展量 计算:

    = (100px × 1) / 3 ≈ 33.33px (保留两位小数)

  • 右元素扩展量 计算:

    = (100px × 2) / 3 ≈ 66.67px (保留两位小数)

步骤4:计算最终宽度

  • 左元素最终宽度 = flex-basis值 + 扩展量
    = 300px + 33.33px
    = 333.33px
  • 右元素最终宽度 = flex-basis值 + 扩展量
    = 200px + 66.67px
    = 266.67px

验证计算:

  • 最终总宽度 = 333.33px + 266.67px
    = 600px (等于容器宽度)
  • 总扩展量 = 33.33px + 66.67px
    = 100px (等于剩余空间)

四、总结

机制 触发条件 核心公式 应用场景
收缩(shrink) 子元素总宽 > 容器 收缩量 = 溢出空间 × (shrink×basis)/总权重 防止内容溢出容器
扩展(grow) 子元素总宽 < 容器 扩展量 = 剩余空间 × (grow / 总grow) 自适应填满容器空间

Flex布局的精髓在于动态分配空间的能力:

  1. 收缩机制优先保护高权重内容(shrink值小的元素收缩少)
  2. 扩展机制实现按比例填充(grow值决定分配比例)
  3. 基准尺寸(flex-basis)是计算的核心锚点
相关推荐
onebyte8bits2 小时前
CSS Houdini 解锁前端动画的下一个时代!
前端·javascript·css·html·houdini
行云流水62613 小时前
js实现输入高亮@和#后面的内容
前端·javascript·css
Bigger15 小时前
🍸 Apple Liquid Glass 设计理念与前端实现解析
前端·css·apple
快起来别睡了18 小时前
CSS定位的奥秘:从文档流到position,一文讲透前端布局核心!
前端·css·程序员
Bottle41421 小时前
关于 CSS 属性值处理
css
走,带你去玩1 天前
uniapp 时钟
javascript·css·uni-app
啃火龙果的兔子1 天前
安全有效的 C 盘清理方法
前端·css
小桥风满袖1 天前
Three.js-硬要自学系列32之专项学习箭头辅助器
前端·css·three.js
睡不着先生1 天前
CSS Houdini解锁前端动画的下一个时代!
javascript·css·html