写点什么

Flexible Box Layout 原理剖析

用户头像
大导演
关注
发布于: 2020 年 08 月 15 日
Flexible Box Layout 原理剖析

flex 布局会创建新的格式化上下文 flex formatting contextflex 容器的子项可以在任何方向上进行布局,并且可以“伸缩”其大小,既可以增长已填充未使用的空间,也可以收缩防止子项溢出。子项的水平和垂直对齐都可以轻松操纵。


在正式开始之前,我们先了解一下排版的一些基础知识。

盒(Box)

排版和渲染的基本单位是(Box),一个元素(Element)在排版时可能产生多个(Box)。一个 <span></span>,从源代码角度而言,它是一个标签(Tag);从语义上来讲,它是一个元素(Element);从表现上来看,它是一个(Box)。


一个 inline-block 元素可能会产生多个盒,我们可以使用 chrome 调试工具选中元素,在控制台输入$0.getClientRects() 来获取行盒。通常情况下,我们用选择器选中的都是元素,而选不到盒本身,但是也有特例,::first-letter 伪元素可以选到盒,它就是首行的首字(母)。


上图是一个 span 标签包裹的元素,产生了 8 个盒,也就是每一行都是一个行盒。

基本术语

Flexible Box Layout Modle


  • flex container

display 的属性为 flex 或者 inline-flex 的元素

tips:

:: first-line:: first-letter 伪元素不适用于 flex container


  • flex item

flex container 的所有子元素,对应得是 flex-level box,而不是 block-level box

tips:

  • 设置 flex 后,flex itemfloatclearvercital-align 属性将失效。

  • 具有绝对定位(脱离文档流)的 flex item 不会参与 flex 布局。


  • main axis

flex container 的主轴


  • cross axis

flex container 的交叉轴


  • main start

主轴的开始位置


  • main end

主轴的结束位置


  • cross start

交叉轴的开始位置


  • cross end

交叉轴的结束位置


  • main size

主轴尺寸


  • cross size

交叉轴尺寸

flex 布局

  1. 收集盒进行(hàng)

根据主轴尺寸 mainSize,把盒分进行;若设置了 nowrap,强行分配进第一行。


flex container 没有设置 mainSize,则 mainSize 为主轴方向的 size 属性之和。可能是 width,也可能是 height,这取决于 flex-direction 的属性值是 row 还是 column



  1. 计算盒在主轴方向的排布

  • 把主轴方向的剩余尺寸按比例分配给 flex item

  • 若剩余空间为负数,所有 flex 元素为 0,等比压缩剩余元素


① 若 flex itemsize 属性之和超出了 mainSize,所有 flex item 置为 0,在主轴方向等比例伸缩。


② 若某一行有剩余空间,且存在 flex item 没有设置主轴方向的 size 属性,width 或者 height。 该子项 flex item 设置 flex: 1,所有设有 flex 属性的元素平分剩余空间。


③ 若设置了 wrapflex itemsize 属性之和超出了 mainSize,则从超出的 flex item 开始放入下一行。


  1. 计算盒在交叉轴方向的排布

  • 根据每一行中最大元素尺寸计算行高

  • 根据行高 flex-alignitem-align,确定元素具体位置


① 交叉轴的尺寸 crossSize 取决于 flex item 在交叉轴方向最大的 size 属性,默认 row 是主轴,则 flex containerheight 属性无论设置多小,还是会被 flex itemheight 属性撑开。


② 若交叉轴有剩余空间,所有 flex item 在交叉轴方向平分剩余空间。



以上只讨论了 flex 布局的部分属性情况,可能在某些属性的作用下,文中表述还存在不严谨的地方,还请见谅,也欢迎大家指正。


Animation 源代码请戳这里

flex 属性

flex: 1flex-growflex-shrinkflex-basis 属性的简写。


  • flex-grow | 属性值语法 <number>

指定了 flex container 中剩余空间的多少应该分配给项目(flex 增长系数)。


  • flex-shrink | 属性值语法只允许 <number>,负值不被允许

指定了 flex item 的收缩规则。flex item 仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。


  • flex-basis | 属性值语法 content 或者 <'width'>

指定了 flex item 在主轴方向上的初始大小。若不使用 box-sizing 改变盒模型的话,这个属性就决定了 flex item 的内容盒(content-box)的尺寸。

参考

推荐阅读


发布于: 2020 年 08 月 15 日阅读数: 868
用户头像

大导演

关注

导演出品,必属精品 2019.01.15 加入

github:https://github.com/directorcn,欢迎 star ⭐

评论

发布
暂无评论
Flexible Box Layout 原理剖析