why Flexbox

450 阅读4分钟

文章介绍早已是老生常谈的Flexbox,主要介绍Flexbox涉及的角色,如flex container、flex item、main axis等等,和Flexbox适用的场景。

why Flexbox

Flexbox是Flexible Box Layout的简称,它帮助我们更加容易地在一个方向上布置元素,不管是横向还是纵向,它是一种一维布局方法。传统的floatposition布局方法难以实现有些情况,比如:

  • 将内容块垂直居中于父级元素
  • 无论容器有多少宽度/高度,使子容器占有相同的可用宽度/高度
  • 在多列布局中所有列采用相同高度,即使包含不同的内容量

Flexbox简单优雅地解决这样的问题,答案在接下来的内容中。

Introducing the flex model

这里有一个最简单的demo-flexbox-start实现3列布局,选择了<section>元素作为了flex container。借助这个例子认识一下flex model中的各个角色/名词:

  • main axis:主轴,主轴的方向是flex item被放置的方向;主轴的起点是main start,终点是main end。在demo中,主轴是横向;
  • cross axis:横轴,横轴的方向是垂直于主轴的延申;横轴的起点是cross start,终点是cross end。在demo中,横轴是纵向;
  • flex container:被设置为display:flex的元素。在demo中,它是<section>元素
  • flex item:放置在flex container内的元素,图片中有main size和cross size描述它的大小。在demo中,它们是3个<article>元素

认清除这些角色/名词能帮助我们更好理解flexbox众多的属性。

Moving deeper

Columns or rows

Flexbox提供了flex-direction属性定义main axis的方向,默认情况是flex-direction:row,也是在前面三列布局demo中的情况。

另外还有flex-direction:columnflex-direction:row-reverseflex-direction:column-reverse等属性值

wrapping

有一种情况是flexbox container有一个设定的宽度/高度,flex items超出了flex container,破坏了布局:demo-flexbox-overflow

在这个demo中的flex container<section>元素添加样式flex-wrap:wrap,超出的情况会移动到下一行。

flex-directionflex-wrap属性的简写是flex-flow,尽量多使用简写,而在之后需要时用详细的属性去覆盖。dd

application1:Flexing sizing of flex items

demo-flexbox-flex 中使用flex属性控制flex items大小、大小如何变化:

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

flex属性是flex-grow(当空间剩余时伸展多少)、flex-shrink(当空间不足时收缩多少)、flex-basis(元素初始大小)。

application 2:Horizontal and vertical alignment

水平和垂直方向的对齐,是将flex items沿着main/cross axis对齐。这里涉及到两个属性align-itemsjustify-content

属性align-item定义了flex items在cross axis方向上怎么排布。有这么几种情况:

  • align-item:stretch:默认值,具体表现为,如果parent元素在cross axis方向设定了一个宽度值,那么所有flex items填满整个parent元素;如果parent元素在cross axis方向没有设定一个宽度值,那么所有flex items按cross axis方向最大的flex item伸展;
  • align-item:center:居中,保持flex items原有长宽值
  • align-item:flex-startalign-item:flex-end:对应cross start和cross end。

这里挂一个demo-flexbox-align-item/align-self。属性align-item是站在flex container角度,为所有flex items设定的统一值,如果flex items想自定义,则设置align-self

属性justify-content定义了内容如何在main axis方向上布置。有这么几种情况:

  • justify-content:flex-start:默认值,从main start开始
  • justify-content:flex-end:从main end 开始
  • justify-content:center:在main axis居中
  • justify-content:space-around:沿着main axis均匀分布所有flex items,左右两端留有一点空间
  • justify-content:space-between:同样也是沿着main axis均分flex items,但左右两端不留有空间

在main axis方向上布置flex items只能是一个整体行为,所有没有供flex items自定义的属性。

application 3:ordering flex items

flexbox提供属性order改变flex items布局时的顺序(而不修改源代码),demo-flexbox-order

order属性值:

  • 初始值order:0
  • 值越大,顺序越后面;值相同,按照源代码顺序
  • 技巧:设置order:-1将flex item置前

application 4:nested flex box

demo-flexbox-nested,也是很常见的情况,flex item也被设为flex container,所以是嵌套。

Cross browser compatibility

支持大部分现代浏览器,IE11+,所以涉及IE10的就得考虑其他布局方式了,因为如果浏览器不支持flexbox,布局就直接被破坏了。

总结

现在在why Flexbox里提出的几个场景有解决方案了吗?揭开答案了(对应上述顺序):

  1. align-items:center
  2. 设置相同的flex值,比如:flex:1
  3. align-items:stretch

在开始使用一个技术之前,考虑为什么要使用这个技术?在css中布局方法有很多,某一种布局方法不可能解决所有的布局场景,势必有优势和劣势。这里flexbox适应的场景在文中有所罗列。

但不足的是没有做下面问题的探究:

  • 什么样的场景flexbox是不适应的?

参考链接:

mdn-Flexbox

mdn-css-layout-introduction