flex布局笔记整理

35次阅读

共计 3084 个字符,预计需要花费 8 分钟才能阅读完成。

flex 布局笔记整理

了解 -webkit-box

利用 postcss 进行 css 代码的向后兼容时,display:flex 兼容后的代码常会带有 display:-webkit-box。
部分移动端内核较低,只支持老版本的 box 布局,不支持 flex 布局。
box 布局是 flex 布局的前身,与 float 不同,float 超出边界时会自动换行,box 和 flex 不会。

box 与 flex 区别

容器部分

  1. 子元素总宽度超过父元素时:
    box => 子元素溢出父元素边界
    flex => 子元素被挤压
    查看对比
  2. 修改排列时的主轴:
    box => -webkit-box-orient: (horizontal | vertical)
    flex => flex-direction: (row | column)
    (效果相同,差异仅是属性名不同)
  3. 排列时的顺序:
    box => -webkit-box-direction: (normal | reverse)
    flex => flex-direction: (row-reverse | column-reverse)
    注:flex 的反转效果,以 row-reverse 为例,是从容器最右边开始排列的,box 反转效果是从容器最左边排列的(查看对比)
  4. 主轴富余空间管理:
    box => -webkit-box-pack:
    / start: 富余空间在右边
    / end: 富余空间在左边
    / center: 富余空间在两边
    / justify;富余空间在项目之间
    flex => justify-content:
    / flex-start 富余空间在左边
    / flex-end 富余空间在右边
    / center 富余空间在两边
    / space-between, space-around, space-evenly 不同形态的富余空间在项目之间
  5. 侧轴富余空间管理:
    box => -weblit-box-align:
    / start: 富余空间在下面
    / center:富余空间在两边
    / end:富余空间在上面
    flex => align-items:
    / flex-start: 富余空间在下面
    / center: 富余空间在两边
    / flex-end: 富余空间在上面
    / baseline: 基线对其
    / stretch: 等高布局

注:4、5 中是相对于主轴和侧轴,并非固定是 X 轴还是 y 轴

项目 (item) 部分

  1. 拉伸与压缩
    box => -webkit-box-flex(既能控制拉伸也能控制压缩)
    flex => flex-grow (只能控制拉伸)、flex-shrink (只能控制压缩)
  2. 宽度设置
    box => width
    flex => width 或 flex-basis,flex-basis 优先级高于 width

flex 布局基础

基本概念可参考一劳永逸的搞定 flex 布局,大部分属性规则都不复杂,参考下图使用即可。需要注意的属性是 flex-grow 和 flex-shrink。

flex-grow 的计算方式

flex-grow 的作用:当主轴方向存在富余空间时,将富余空间赋予对应 item
flex-grow 默认值:0
flex-grow 触发条件:主轴方向存在富余空间
flex-grow 对于富余空间计算:富余空间根据 flex-grow 数值进行分配
例:
假设 content 宽度为 600px,flex 布局,其内部有 4 个 item,item 初始宽度分别为 50px、100px、150px、200px。
第 1 个 item 的 flex-grow:4;
第 4 个 item 的 flex-grow:1;
Q:求 4 个 item 的宽度分别为多少?
解:

  1. 计算富余空间宽度:
    富余 = 600px - (50+100+150+200)px = 100px
  2. 计算单位 flex-grow 的分配宽度:
    单位 flex-grow 宽度 = 富余 /(flex-grow 总和) = 100px/(4+1) =20px
  3. 按照 flex-grow 数值分配宽度:
    第 1 个 item 宽度 = 初始宽度 + 单位 flex-grow 宽度 *flex 值 = 50px + 20px*4 = 130px
    第 4 个 item 宽度 = 初始宽度 + 单位 flex-grow 宽度 *flex 值 = 200px + 20px*1 = 220px

因此,4 个 item 宽度分别为 130px、100px、150px、220px。可查看实例

flex-shrink 的计算方式

flex-shrink 的作用:当容器 flex-wrap 为 nowrap,且 item 初始宽度之和大于容器宽度时,容器会对其中的 item 进行压缩,flex-shrink 决定压缩时的规则。
flex-shrink 默认值:1
flex-shrink 触发条件:容器宽度不够,需要压缩内容显示
flex-shrink 计算方式:

  1. 计算压缩空间
  2. 每个 item 权重 = flex-shrink * 宽度,根据权重分配压缩空间
  3. 是否有 item 会被压缩至 0 宽度,若有则假设这些 item 宽度为 0,重新进行压缩空间分配计算

注:当 item 中有内容时,item 被压缩的最小宽度为内容宽度

例:假设 content 宽度为 300px,flex 布局,其内部有 4 个 item,item 初始宽度分别为 50px、100px、150px、200px。
Q1:4 个 item 实际显示的宽度为多少?
item1 的 flex-shrink 设为 10;
item4 的 flex-shrink 设为 5;
Q2: 4 个 item 的宽度分别为多少?
解:
Q1:

  1. 计算压缩空间宽度
    压缩 = (50+100+150+200)px - 300px = 200px
  2. 分配压缩空间
    4 个 item 宽度比为 1:2:3:4,初始 flex-shrink 为 1
    单位权重宽度 = 200px/(1*1+2*1+3*1+4*1) = 20px
    第 1 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 50px - 20px*1*1 = 30px
    第 2 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 100px - 20px*2*1 = 60px
    第 3 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 150px - 20px*3*1 = 90px
    第 4 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 200px - 20px*4*1 = 120px
  3. 是否需要重新计算
    由于步骤 2 计算的 item 宽度都大于等于 0,因此不需要重新计算

因此,4 个 item 宽度分别为 30px、60px、90px、120px。

Q2:

  1. 计算压缩空间宽度
    压缩 = (50+100+150+200)px - 300px = 200px
  2. 分配压缩空间
    4 个 item 宽度比为 1:2:3:4,item1、item4 的 flex-shrink 分别为 10、5,其余 flex-shrink 为 1
    单位权重宽度 = 200px/(1*10+2*1+3*1+4*5) = 40/7px
    第 1 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 50px - 40/7px*1*10 = -7.14px
  3. 是否需要重新计算
    由于第 1 个 item 计算后的宽度为 -7.14px<0,因此需要重新分配压缩空间
  4. 计算压缩空间宽度
    由于上一步中 item1 宽度小于 0,将 item1 宽度当作 0,重新计算压缩空间宽度
    压缩 = (100+150+200)px - 300px = 150px
  5. 分配压缩空间
    单位权重宽度 = 150px/(2*1+3*1+4*5) = 6px
    第 1 个 item 宽度 = 0
    第 2 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 100px - 6px*2*1 = 88px
    第 3 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 150px - 6px*3*1 = 132px
    第 4 个 item 宽度 = 初始宽度 - 单位权重宽度 * 权重 = 200px - 6px*4*5 = 80px
  6. 是否需要重新计算
    由于步骤 5 计算的宽度都大于等于 0,因此不需要重新计算

因此,4 个 item 宽度分别为 0、88px、132px、80px。可查看实例
注意:给 item 添加文字后,宽度无法压缩为 0,压缩空间计算将更为复杂。

正文完
 0