阅读 371

[译] Flexbox 的使用场景

原文:Use Cases For Flexbox, by Rachel Andrew

摄影 | Free-Photos

本文是 Flexbox 系列的最后一篇文章。文本我将花时间说明 Flexbox 的使用场景,而且我们现在还有 Grid 布局,我会对如何在他们之间做选择和各的使用场景做些说明和建议。

系列早期文章

如果你还没有读这个系列的其他文章的话,现在可以先去看看一下。我先讲了 当我们在使用 display: flex 的时候,发生了什么;第二篇则看了下 对齐,讲了如何在主轴和交叉轴上做对齐操作;第三篇讲了 Flexbox 中盒子尺寸的形成原理,以及浏览器默认是如何分配盒子尺寸的。现在我们已经明白了 Flexbox 的工作原理,现在通过总结来思考它最适合的用例场景。

我该用 Grid 还是 Flexbox 呢?

这是我在教授布局过程中,经常被问到的一个问题,我发现当人们开始渐渐习惯使用这些新的布局方法后,这个问题就不再是问题了。在你写了许多组件样式后,就会知道怎么合理利用这些布局方法了。

如果你非要弄清楚到底怎么回事的,那么你首先要记住的就是 Grid 布局和 Flexbox 布局都是 CSS。不论你是使用 dispaly: grid 还是 display: flex,你使用的通常是它们较为通用的部分,而非不同的部分。Grid 和 Flexbox 中都用到了 Box Alignment 规范中定义的属性,它们两者都使用了 CSS 内在尺寸和外在尺寸详细陈述各自的概念。

询问该用 Grid 还是 Flexbox,就像是询问我是应该用 font-size 还是 color 。答案是按照需要,两者都可以使用。如果你不小心用错了,也不会有人怪你的(效果总是有的嘛,灵不灵活另说)。

因此,我们不是在 Vue.js 和 React.js 之间选择,也不是在 Bootstrap 和 Foundation 之间做选择。我们只是使用 CSS 去布局,使用最适合我们当前设计的那一部分 CSS 特性。考虑每个组件使用哪一种布局最合适,或者使用哪种组合方式会产生最好的布局效果。

它可能是 Grid,也可能是 Flexbox。可能外部是一个 Grid 容器,Grid 项目中某一些是 Flex 项目,或者反过来。如果设计需要,在一个 Flex 项目中嵌套一个 Grid 容器是没问题的。

Flexbox 是用来干什么的?

Flexbox 规范中是这样描述的:

“Flexbox 表面上跟块布局(block layout)很像。但它缺乏许多可以在块布局中使用的以文本或文档为中心的复杂属性,比如浮动和列(cloumns)。相反,它使用简单而强大的工具,处理复杂 Web 应用中经常遇到的空间分配和内容对齐问题。”

我认为这里的关键字是“空间分配和内容对齐”。Flexbox 把一堆东西(有不同的尺寸)包括在一个容器中(容器本身的尺寸也是可能改变的)。Flexbox 非常温柔,它尝试为所有项目找到最佳的显示方式,给大的项目分配更多的空间,小的项目则被分配较少的空间,以便保证内容的可读性。

当你在某一时刻会感觉使用 Flexbox 很不顺手或不舒服的时候,说明你正在将 Flexbox 作为网格系统使用——尝试控制尺寸和空间的分配。此种情况,你就是在跟 Flexbox 的天然弹性特质做反抗。

因此,适合 Flexbox 的场景是,你不是在布局一个精确到像素级别的 Flex 项目,只是想让这些项目一个个挨着、体面的排列好就行了。

See the Pen Smashing Flexbox Series 4: Items Sharing Space by Rachel Andrew

另一个会遇到的场景是项目折行,但你不想要一个严格的网格式折行(就是对的一齐一齐的)。我们可以使用 Grid 中为我们提供的创造性关键字 auto-fill 来与折行的 Flexbox 布局例子做下对比。就能立马看出它们的不同点。

在 Grid 布局案例中,Grid 项目在行和列上都是一一对齐的,虽然 cloumn track 的数量在改变(依赖于当前空间),但是 Grid 项目都是根据当前的可用空间布局下一个 Grid 单元格的位置。实际上,我们无法让一个 Grid 项目跨列(span tracks),即使在这种自动流(auto-flow)的场景,存在一些空的单元格位置。

See the Pen Smashing Flexbox Series 4: Grid Example by Rachel Andrew

Flexbox 布局例子中,最后一个 Flex 项目则会占据满那一行里的剩余空间。这样的话,我们就没法做水平或者垂直方向上的对齐了。

See the Pen Smashing Flexbox Series 4: Wrapped Items flex-basis: auto by Rachel Andrew

如果使用的是 flex-basis auto(上面 Flex 项目使用的是 flex: 1 1 150px;),那么内容多的 Flex 项目会分得更多的空间,因此行与行之间的对齐效果就非常不同了。

See the Pen Smashing Flexbox Series 4: Wrapped Items by Rachel Andrew

当然,也有比较适合使用 Flexbox 布局而非 Grid 布局的场景。比如我们需要项目折行显示,同时逐行按照自身情况为项目分配空间。这是一种不同形式的“网格布局”。对应到真实场景比如说有一系列的标签(由一或两个单词组合而成的以集合的形式显示的一组元素),它们每个只是占据了需要的空间,不会强制在一个严格的网格布局之中。

See the Pen Smashing Flexbox Series 4: Tags example by Rachel Andrew

现在,Flexbox 是最好的操作容器中项目水平、垂直居中的方法。

See the Pen Smashing Flexbox Series 4: Center an Item by Rachel Andrew

未来(在弹性布局之外,浏览器还支持 Box Alignment 属性的话),我们可能在不需要添加 dispplay: flex 的时候, 就能实现这个效果。现在,我们还是要这样写——不过多出的这一行代码也没啥的。

Flexbox 非常适合处理一行的、包含一组组件的样式布局。我们在不需要在意每个项目尺寸的情况下就可以灵活的实现信息的布局,比如表单控件集合或者 ICON 集合。

See the Pen Smashing Flexbox Series 4: Simple Row of Form Elements by Rachel Andrew

还有一个你会选择 Flexbox 的场景就是在内容不满一屏的布局中,将底部元素内容固定在底部。下面例子中,容器是 Flex 容器,Flex 项目按照 column 方向布局,我们设置中间部分的内容块是可延伸(grow)的,这样底部内容就被推倒视口的最下面了。

See the Pen Smashing Flexbox Series 4: Sticky Footer Card by Rachel Andrew

生产环境下,我们发现 Flexbox 布局非常适合用来做一些细小的工作,比如用来做好对齐,在项目之间很好地分配空间。当然,对于这这些事情,你也可以用“一维式 Grid 布局”来实现,而不用担心说这样用对还是不对。

Flexbox 表现上另外做的很好的一点就是,当我们有一天忽然在之前的设计之外再添加东西时候非常有帮助。比如,我们设计了一个导航栏组件,如果使用的是 Grid,那么我们需要为所有的导航项目设计好我们的 Tracks ,当“项目多起来”的话,按照之前的设计,项目就会折行,打我们不希望折行。用 Flexbox 的话,情况就不一样了,使用 Flexbox,我们不论将项目 flex-basis 设置为 0 还是 auto ,最终的布局结果都是灵活的,已有的项目会为新加入的项目腾出空间展示。

什么时候我不会使用 Flexbox?

上面我介绍了使用弹性布局(而非网格布局)的场景,现在我们来看一些不适合使用 Flexbox 布局的场景。我们已经看见了一行一行排列的项目,在垂直或水平方向上对齐的例子。这就是第一个我们要与 Grid 布局区别的地方。

网格布局属于二维布局,能同时实现在行和列上的对齐。Flexbox 则属于一维布局,多行 Flex 项目的 Flex 容器是逐行分配空间的,每一行(flex line)在表现上都像是一个新的 Flex 容器。

因此如果你的组件需要在二维上进行布局,不管组件本身是大是小,你最好使用 Grid 而非 Flexbox。读完这篇文章,也是我最想让你知道的一件事就是,千万不要有这种想法:Grid 主要是负责页面主体布局的,而 Flexbox 则主要负责组件布局的。实际情况是,你可以有一个很小组件使用的是 Grid 布局,而主体页面结构使用的则是 Flexbox 布局。

另一个考虑 Gird 才是较好布局方案的场景是:为了跟毗邻行上的 Flex 项目产生对齐效果,你给 Flex 项目设置一个 width 或者给项目设置同一个长度的 flex-basis,这样做的目的就是为了限制弹性效果。这通常表示你需要是一个二维布局方案,来自于 Grid 容器的控制会更合适些。

当然,通过限制 Flex 项目的弹性特质,我们可以让 Flex 布局看上去像是网格。举个例子,将 flex-grow 设置为 0,给 Flex 项目一个百分比尺寸,按照同样方式,我们能制造出一个“浮动的网格”效果。如果你发现你正在做这些,我建议你还是使用 Grid 布局,Grid 非常适合这类布局。

See the Pen Smashing Flexbox Series 4: Wrapped Flex Items with Percentage Widths by Rachel Andrew

最后需要记住的是,针对同一个问题,通常不会有非常清楚的错误或正确答案。我们唯一能做的就是多做尝试,看看这个组件到底适合何种布局。当然也可以切换布局方法,在某个断点下使用 Flexbox 布局,而在另一个断点下使用 Grid 布局。

总结

我希望这一系列的几篇文章,能够帮助你理解 Flex 项目在对齐和尺寸分配上的疑惑,让你在使用弹性布局时更加得心应手。如果你还是没有理解或是对该使用哪种布局方法抱有不确定的态度,欢迎在下方评论区留言。

(完)

关注下面的标签,发现更多相似文章
评论