快速!Flexbox 和 Grid 之间有什么区别?

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。从 $200 的免费积分开始!

让我们快速地尝试用简短的要点来回答这个问题,而不是长篇大论。Flexbox 和 Grid 之间有很多相似之处,从它们用于布局,并且比之前任何布局技术都要强大开始。它们可以拉伸和收缩,它们可以居中内容,它们可以重新排序内容,它们可以对齐内容……有很多布局场景,您可以使用其中任何一个来完成我们需要做的事情,还有很多场景,其中一个比另一个更适合。让我们关注差异,而不是相似之处。


Flexbox 可以可选地换行如果我们允许 flex 容器换行,当 flex 项目填满一行时,它们会换行到下一行。它们在下一行上的排列方式独立于第一行上的排列方式,从而可以实现类似砌块的外观。

Grid 也可以选择性地换行(如果我们允许自动填充),因为项目可以填充一行并移动到新行(或自动放置自己),但是当它们这样做时,它们将沿着与所有其他元素相同的网格线排列。

Flexbox 在顶部,Grid 在底部

您可以将 flexbox 视为“一维的”。虽然 flexbox 可以创建行和列,因为它允许元素换行,但没有办法声明性地控制元素最终出现在哪里,因为元素只是沿着单个轴线推进,然后根据需要换行或不换行。它们按其方式进行,如果您愿意,沿着一个一维平面,正因为如此,我们才能选择性地执行某些操作,例如沿基线对齐元素——这是 grid 无法做到的。

.parent {
  display: flex;
  flex-flow: row wrap; /* OK elements, go as far as you can on one line, then wrap as you see fit */
}

您可以将 grid 视为“二维,因为我们可以(如果我们想)声明行和列的大小,然后根据我们的选择将内容明确地放置到行和列中。

.parent {
  display: grid;
  grid-template-columns: 1fr 3fr 1fr; /* Three columns, one three times as wide as the others */
  grid-template-rows: 200px auto 100px; /* Three rows, two with explicit widths */
  grid-template-areas:
    "header header header"
    ". main sidebar"
    "footer . .";
}

/*
  Now, we can explicitly place items in the defined rows and columns.
*/
.child-1 {
  grid-area: header;
}

.child-2 {
  grid-area: main;
}

.child-3 {
  grid-area: sidebar;
}

.child-4 {
  grid-area: footer;
}
Flexbox 在顶部,Grid 在底部

我并不是最喜欢“1D”与“2D”区分 grid 与 flexbox 的人,仅仅是因为我发现我日常使用 grid 的大部分时间都是“1D”,而且它非常适合此目的。我不希望有人认为他们必须使用 flexbox 而不是 grid,因为 grid 只是在您需要 2D 时才使用。但这确实是一个强有力的区别,即 2D 布局是可能的通过 grid,而 flexbox 不行。


Grid 主要在父元素上定义。在 flexbox 中,大多数布局(除了最基本的部分)都在子元素上完成。

/*
  The flex children do most of the work
*/
.flexbox {
  display: flex;
  > div {
    &:nth-child(1) { // logo
      flex: 0 0 100px;
    }
    &:nth-child(2) { // search
      flex: 1;
      max-width: 500px;
    }
    &:nth-child(3) { // avatar
      flex: 0 0 50px;
      margin-left: auto;
    }
  }
}

/*
  The grid parent does most of the work
*/
.grid {
  display: grid;
  grid-template-columns: 1fr auto minmax(100px, 1fr) 1fr;
  grid-template-rows: 100px repeat(3, auto) 100px;
  grid-gap: 10px;
}

Grid 更擅长重叠。使元素在 flexbox 中重叠需要查看传统的东西,例如负边距、转换或绝对定位,以便摆脱 flex 行为。使用 grid,我们可以将项目放置在重叠的网格线上,甚至直接放置在相同的网格单元格中。

Flexbox 在顶部,Grid 在底部

Grid 更稳定。虽然 flexbox 的伸缩性有时是它的优势,但 flex 项目的大小计算起来相当复杂。它是一个组合widthmin-widthmax-widthflex-basisflex-growflex-shrink,更不用说里面的内容以及像white-space这样的东西,以及同一行中的其他项目。Grid 有一些有趣的占位功能,例如分数单位,以及内容破坏网格的能力,尽管一般来说,我们正在设置网格线并将项目放置在它们中,这些项目会直接到位。


Flexbox 可以将内容推开。这是 flexbox 的一个相当独特的功能,例如,您可以将margin-right: auto;放在一个元素上,如果存在空间,该元素会尽可能地将其他所有元素推开。


以下是我最喜欢的关于这个主题的一些推文