首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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 布局的部分属性情况,可能在某些属性的作用下,文中表述还存在不严谨的地方,还请见谅,也欢迎大家指正。

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)的尺寸。

参考

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/24fd0d92d640f139f5791a983
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com