flex 布局会创建新的格式化上下文 flex formatting context,flex 容器的子项可以在任何方向上进行布局,并且可以“伸缩”其大小,既可以增长已填充未使用的空间,也可以收缩防止子项溢出。子项的水平和垂直对齐都可以轻松操纵。
在正式开始之前,我们先了解一下排版的一些基础知识。
排版和渲染的基本单位是盒(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 itemflex container 的所有子元素,对应得是 flex-level box,而不是 block-level box
tips:
flex 后,flex item 的 float、clear、vercital-align 属性将失效。flex item 不会参与 flex 布局。main axisflex container 的主轴
cross axisflex container 的交叉轴
main start主轴的开始位置
main end主轴的结束位置
cross start交叉轴的开始位置
cross end交叉轴的结束位置
main size主轴尺寸
cross size交叉轴尺寸
根据主轴尺寸 mainSize,把盒分进行;若设置了 nowrap,强行分配进第一行。
若 flex container 没有设置 mainSize,则 mainSize 为主轴方向的 size 属性之和。可能是 width,也可能是 height,这取决于 flex-direction 的属性值是 row 还是 column。
flex itemflex 元素为 0,等比压缩剩余元素① 若 flex item 的 size 属性之和超出了 mainSize,所有 flex item 置为 0,在主轴方向等比例伸缩。
② 若某一行有剩余空间,且存在 flex item 没有设置主轴方向的 size 属性,width 或者 height。 该子项 flex item 设置 flex: 1,所有设有 flex 属性的元素平分剩余空间。
③ 若设置了 wrap,flex item 的 size 属性之和超出了 mainSize,则从超出的 flex item 开始放入下一行。
flex-align 和 item-align,确定元素具体位置① 交叉轴的尺寸 crossSize 取决于 flex item 在交叉轴方向最大的 size 属性,默认 row 是主轴,则 flex container 的 height 属性无论设置多小,还是会被 flex item 的 height 属性撑开。
② 若交叉轴有剩余空间,所有 flex item 在交叉轴方向平分剩余空间。
以上只讨论了 flex 布局的部分属性情况,可能在某些属性的作用下,文中表述还存在不严谨的地方,还请见谅,也欢迎大家指正。
flex: 1 是 flex-grow、flex-shrink、flex-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)的尺寸。