- 原文地址:To Grid or to Flex?
- 原文做者:Michelle Barker
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:Reaper622
- 校对者:xionglong58,hanxiansen
一个最近由 Chris Coyier 发起的的 推特话题 使我开始思考人们一般在什么状况下使用 CSS Grid 布局仍是 Flexbox 布局:css
对于已经理解了 CSS grid 和 flexbox 的大家来讲,最喜欢的描述两者之间差别的方法是什么?前端
— Chris Coyier (@chriscoyier) January 25, 2019android
天然地一些最有见地的回复来自于 Rachel Andrew 和 Jen Simmons:ios
Flexbox 是一种一维布局。一行或者一列。Grid 是一种二维布局。多行和多列。git
— Rachel Andrew (@rachelandrew) January 25, 2019github
Grid 创造了实际的列和行。内容会按你要求的一个接一个地排列整齐。Flexbox 则不会。不止是在二维(最显而易见的),一样也在一维条件下,Flexbox 并不适用于当今咱们一直使用它的大部份内容。算法
— Jen Simmons (@jensimmons) January 26, 2019后端
然而,只是单单阅读推文并不会告诉咱们始末。这篇文章旨在告诉读者二者的适用场景,以及在哪一种状况下只能选择使用其中一个。浏览器
当浏览话题下面的回复时,我发现至关大数量的人只在页面级的布局中使用Grid,其余状况下直接使用 flexbox。若是你把这个当成一条准则,那么你在严重地限制本身使用 Grid 的强大的功能。我特别建议:把每一个设计独立化,分析可选方案的可行性,不要对你使用的技术来作出主观的猜测。当你选择一种布局方法时,先扪心自问一下下面的这些问题。bash
这是我对这个话题的发出的推文:
当我看起来彷佛须要
calc()
对布局使用大量的计算时,Grid 是一个更好的选择。— Michelle Barker (@mbarker_84) January 26, 2019
一般地,若是你不得不大量的使用 calc() 来获得精确地位置与尺寸(例如考虑到间隔的状况),那么一般是值得去考虑一下使用 Grid 的,由于 fr 单位会帮咱们作繁重的适配,它会让你不那么头痛。虽然做为通常准则这很不错,但也并非适用于全部的场景。这是一些你可能会用到 Grid 的场景,即便你的布局并不须要大量的 calc()。一个例子是一个固定宽度的二维布局,每一个网格轨道是 200px 宽 - 你不须要 calc() 来告诉你网格轨道应该是多宽,但你可能仍然想要 Grid 的表现行为。一样,有些你须要计算的状况下也会使用 flexbox,所以这只能做为一个指南。
Grid 和 flexbox 的一个很大的差别是 Grid 容许咱们在二维空间(多行多列)控制元素的位置,flexbox 则不行。再强调一次,那并不意味着你永远不能在一维布局中使用 Grid。我常常在我须要准确地在一维空间控制元素的尺寸和位置时选择使用 Grid。就像在这个示例和随附的文章中:
在 CodePen 上查看 Michelle Barker (@michellebarker) 写的 带有变量和媒体查询的 CSS Grid 组件
Grid 一般在你须要控制二维空间的布局时是一个正确的选择。但它不意味着对任何状况来讲都是一个更好的选择。Grid 给你带来的网格轨道(多行和多列),网格单元以及网格区域(多个网格单元组成的组)而且元素必须被放置在这些网格单元或者 Grid 区域。咱们可使用 Grid 或 flexbox 进行布局,不过 Grid 布局相较起来更加简单明了。
假设咱们有这样的布局:
咱们有一个由九个等宽的元素组成的网格,从上到下排成三排,每一个元素之间有 20px 的间隙:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
/* 假设咱们想要咱们的行都是一个固定的高度 - 若是咱们想要高度响应地根据内容变化,能够保留为默认的 `auto` */
gap: 20px;
}
复制代码
元素以后就被自动放置,不须要咱们再作其余的事情了。若是咱们真的想要它变得很是灵巧,咱们可使用 Grid 的 auto-fit() 和 minmax() 方法来给咱们一个不须要媒体查询的彻底响应式的布局 - 尝试调整此示例的大小,看看会发生什么。
在 CodePen 上查看 Michelle Barker (@michellebarker) 的 Grid 自适应例子。
我推荐观看 Heydon Pickering 的视频 算法布局 来做为一个对这个技术的概述等。
相反地,若是咱们想要使用 flexbox 建立这个布局,咱们可能要设置实际的元素和网格容器的样式:
.grid {
display: flex;
flex-wrap: wrap;
margin: -10px;
width: calc(100% + 20px);
}
.item {
width: calc((100% / 3) - 20px);
flex: 0 0 auto;
margin: 0 10px 20px 10px;
}
复制代码
咱们须要在网格容器上使用负 margin 来抵消这一事实 —— 内部元素的总的宽度可能要比容器更大,所以它会被换行到下一行。咱们也没有了开箱即用的响应式行为而且极可能须要使用媒体查询。
在 CodePen 上查看 Michelle Barker (@michellebarker) 的 Flexbox 布局示例。
使用 flexbox 能够经过几种不一样的方式实现相同的布局,但他们都让我感受有点复杂 - 它们原本就是那么复杂。咱们将 flexbox 用于并非它真正被设计出来要作的事 — 但并不意味着它老是错误的选择。
许多现代 CSS 框架对此布局使用此方法的一些变体。做为旁注,你若你真的要继续走这条路,我由衷地向你推荐 Susy,它能够帮你处理大量的计算。
因此,什么是更好的选择 — Grid 仍是 flexbox?彷佛 Grid 有一些明显的优点,但为了回答这个问题,咱们须要考虑当咱们有超过 9 个可是少于 12 个元素(下一个容许他们填充一行的多个元素)时会发生什么。咱们想要新元素就像咱们已经看到的同样干脆直接放置在下一行的开始?又或是咱们想要它表现的不同?也许下一行就只有一个元素,咱们但愿它占用行全部的可用空间,就像下面的实例A。或者若是有两个元素,那么咱们但愿它们居中,就像下面的示例 B。
使用 Grid 布局和自动放置,咱们只能选择将最后一项放在左侧的单元格中,就像前面的例子所示 — 假设 direction 的值未设置为 rtl
(在这种状况下元素会被按从右到左的顺序放置,最后一项会放置在右侧的单元格)。
在 CodePen 上查看 Michelle Barker (@michellebarker) 的 Flexbox 布局示例。
因此不管你为上面的布局选择 Grid 或者 flexbox,实际上均可归结为你但愿你的网格元素的响应变化 - 而且可以针对不一样的状况有不一样的效果。
当我演讲时,我常常被问到什么时候应该使用 flexbox 而不是 Grid,以及咱们是否还须要 flexbox。在以前的例子里咱们已经知道,Grid 不是 flexbox 的替代品。他们二者能够很是愉快的共存,而且知道什么时候使用它们能够为你的布局提供更多的动力。
在上面的组件中,咱们须要控制文本、图片以及横走坐标轴上的标题的位置,并控制它们如何在必定程度上相互交互。满意的实现这个效果的方法只能是使用 Grid。
但我绝对会用 flexbox 来构建一个桌面导航菜单:
在 CodePen 上查看Michelle Barker (@michellebarker) 的Flexbox 导航。
这里我只想控制单维度的流,而且我想要元素是响应式 - 这也是 flexbox 作的至关出色的地方。使用 flexbox 咱们能够选择这些元素是否换行,并在全部项目没法显示在一行的状况下容许他们优雅地换行。
若是咱们使用 Grid,另外一个咱们须要考虑的问题是浏览器是否支持以及咱们想要在不支持的浏览器(IE11 及如下版本)上让咱们的布局如何展现:
.grid {
display: flex;
flex-wrap: wrap;
/* 其他的后备布局代码 */
}
@supports (display: grid) {
.grid {
display: grid;
/* 其他的 Grid 布局代码 */
}
}
复制代码
然而,若是你发现你本身花费数小时的时间来试图为不支持 Grid 的浏览器复制彻底相同的布局,那么可能一开始就不应 Grid。Grid 的好处是它能够作一些 flexbox 单独作不到的事情。
咱们在这里讨论了一些很是简单,常见的布局的例子和如何使用 Grid 和 flexbox 来实现它们。若是想要看一些其余的复杂的例子,能够看一下这篇博客中的其余文章,或者继续关注我将来的更多帖子。
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。