网格vs flexbox:你应该选择哪个?

kunal sarker. 经过 kunal sarker.  |  2018年9月26日

CSS. Grid和CSS Flexbox是多年来被热量预期的免费Web布局技术。但是,尽管它们实际上用于非常不同的任务;他们每个都解决了一个非常不同的问题。

在一个理想的方案中,您可能会发现您雇用不同的布局任务。在这篇文章中,我们将看看他们的差异,看看他们如何解决各种布局问题,并帮助您选择哪些(如果要么)是您的问题的正确解决方案。

 

网格是基于集装箱的,FlexBox是基于内容的

在Flexbox布局中,单元格的大小 (Flex-Item) 在Flex-Item本身内部定义,并在网格布局中,小区的大小 (网格项目) 在网格容器内定义。

令人困惑?

让’看看一个例子,这里’s html创建一行元素:

<div class="row">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>

我们使用Flexbox如此符合此操作:

。排 {
    margin: 20px auto;
    max-width: 300px;
    display: flex;
}
.row > div {
    border: 1px dashed gray;
    flex: 1 1 auto; /* Size of items defined inside items */
    text-align: center;
    padding: 12px;
}

我们通过设置定义了Flex-Item内的单元格的大小 Flex:1 1 Auto;。这 柔性 财产是简写的 灵活成长, Flex-Shrink., 和 弯曲基础 一个陈述中的属性;它的默认值是 0 1自动。通知 “排” div是柔性容器,我们不’T设置那里物品的大小。我们在Flex-Item中设置大小。

在浏览器中预览时,我们会获得一行框,正如您所期望的那样:

screencap-1

现在让我们看看我们如何使用网格生成相同的输出:

。排 {
    margin: 20px auto;
    max-width: 300px;
    display: grid;
    网格模板列: 1fr 1fr 1fr 1fr; /* Size of items defined inside container */
}
.row div {
    border: 1px dashed gray;
    text-align: center;
    padding: 12px;
}

以上代码将为我们提供完全相同的输出。

注意,现在我们正在定义单元格的尺寸 网格模板列 在网格容器内部 (。排), not the grid-item.

这是一个重要的区别。它表明计算Flexbox布局 其内容加载,而网格布局是计算的,而不管它内部的内容如何。 因此,如果可能,避免使用FlexBox构建您网站的整体布局。

 

网格有一个“差距”属性,Flexbox没有

您可以争辩说,Flexbox和Grid之间的主要区别在于,在后者中,我们可以在介于之间创建排水沟 网格项目 使用 网格柱间隙, like so:

screencap-2

为了在Flexbox中实现相同的结果,我们必须使用填充和嵌套容器,或增加Flex-Container的宽度并使用 证明 - 内容 分布的财产 Flex-intern。

我们必须在Flexbox中乘坐迂回路线,因为它没有一个 差距 财产。但是,它就在路上;这 CSS.框对齐模块3 包含与所有布局模式的框对齐的CSS功能:块布局,表布局,Flex布局和网格布局。框对齐模块收集FlexBox,网格和多列的属性,可以在所有布局模型中一致地使用。最终我们将能够添加空白 行差距柱间隙 属性,但尚未。

 

FlexBox是一维的,网格是二维

自从我们使用表格布局以来,我们一直在Web上将元素安排为Web上的行和列。 Flexbox和Grid都基于此概念。 Flexbox最适合在单行或单个列中安排元素。网格最适合在多行和列中安排元素。

换句话说,FlexBox是一维的,并且网格是二维。让我们看一下常用的一维布局–社交份额按钮:

所有元素都在单行中。我们可以使用这样的FlexBox实现这一点:

<ul class="social-icons">
  <li><a href="#"><i class="fab fa-facebook-f"></i></a></li>
  <li><a href="#"><i class="fab fa-twitter"></i></a></li>
  <li><a href="#"><i class="fab fa-instagram"></i></a></li>
  <li><a href="#"><i class="fab fa-github"></i></a></li>
  <li><a href="#"><i class="fas fa-envelope"></i></a></li>
  <li><a href="#"><i class="fas fa-rss"></i></a></li>
</ul>

.social-icons {
  display: flex;
  list-style: none;
  justify-content: space-around;
}

证明 - 内容 属性确定Flex-Container的额外空间是如何分配给Flex项目的。这 空间周围 值以这样的方式分发空间,使得Flex-inters将均匀地放置在周围的相同数量的空间。

接下来,让我们看一下常用的二维布局:

我们无法使用单行或单个列实现此布局,我们需要多行和列来执行此操作,这就是我们使用CSS网格的地方。让我们使用CSS网格:

<div class="container">
  <header>Header</header>
  <main>Main</main>
  <aside>Aside</aside>
  <footer>Footer</footer>
</div>

和CSS:

.container {
  max-width: 800px;
  margin: 2em auto;
  display: grid;
  网格模板列: 3fr 1fr;
  grid-template-rows: repeat(3,auto);
  grid-gap: 1rem;
}

.container header {
  grid-area: 1/1/2/3;
}

.container main {
  grid-area: 2/1/3/2;
}

.container aside {
  grid-area: 2/2/3/3;
}

.container footer {
  grid-area: 3/1/4/3;
}

.container > * {
  background-color: #ddd;
  padding: 1rem;
}

我们正在使用使用的两个列 网格模板列 财产,以及三行使用 网格模板行 财产。这 重复() 函数创建3行 汽车 height.

然后,在网格中的项目内 (标题, 主要,旁边和页脚)我们定义了这些网格物品将使用多少覆盖范围 网格区 property.

 

Flexbox包裹网格包裹

当容器内部的物品的总宽度大于容器的宽度时,在这种情况下,布局模型都可以选择将物品包装到新行。但是,句柄包装的方式不同。

让我们通过构建示例布局来看看这种差异。创建两行并将6个div位于每行内:

<h2>Flexbox</h2>
<div class="row-flex">
    <div>1 2 3  4 5 6 7 8 9 0</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
</div>
 
<h2>Grid</h2>
<div class="row-grid">
    <div>1 2 3  4 5 6 7 8 9 0</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
</div>

现在,我们将使用FlexBox来布局第一行和网格第二:

/* Flexbox row styles */
.row-flex {
  margin: 40px auto;
  max-width: 600px;
  display: flex;
  flex-wrap: wrap;
}
.row-flex div {
  border: 1px dashed gray;
  flex: 1 1 100px;
  text-align: center;
  padding: 12px;
}
/* Grid row styles */
.row-grid {
  margin: 40px auto;
  max-width: 600px;
  display: grid;
  网格模板列: repeat(auto-fill, minmax(100px, 1fr));
}
.row-grid div {
  border: 1px dashed gray;
  text-align: center;
  padding: 12px;
}

对于第一行,我们正在使用 Flex:1 1 100px 为Flex-item提供100px的基础宽度并允许其生长和缩小。

我们还可以通过设置通过设置柔性容器内的柔性物品包装 柔性缠绕 财产 ,它的默认值是 noprop..

对于第二行,我们正在使用 网格模板列s 属性要创建列最小宽度100px的列 米纳克斯() 功能。我们正在使用 重复() 函数重复创建列。

您可以看到网格和Flexbox的美丽,位于延伸和挤压物品的能力,基于可用的空间量。 Flexbox实现了此目的 灵活成长Flex-Shrink. 属性,网格使用组合实现这一目标 米纳克斯自动填充 内部的功能 网格模板列 property.

但是,仔细看看细胞 5 和细胞 6 因为他们被推到了。在Flexbox,单元格 56 当按下时与其他单元格的大小不同。虽然在网格的情况下,它们将与网格中的所有其他单元格保持相同的大小。

这发生了因为当在新行包装并按下Flex-Item时,Flexbox布局算法将其视为a的一部分 不同的 柔性容器。因此,推动的物品失去了其背景。

此行为可以在某些用例中使用,例如,电子邮件用户表单:

让’s build this subscriber form:

<div class="subscriber-form-container">
  <form>
    <input type="email" placeholder="Email Address">
    <input type="text" placeholder="Name">
    <input type="submit" value="Subscribe">
  </form>
</div>

并在我们的CSS中给予一些样式:

.subscriber-form-container {
  max-width: 650px;
  margin: 40px auto;
  border: 1px dashed gray;
  box-sizing: border-box;
}
.subscriber-form-container form {
  display: flex;
  flex-wrap: wrap;
}
.subscriber-form-container form input {
  margin: 6px;
  padding: 0.4rem;
  box-sizing: border-box;
}
.subscriber-form-container form input{
  flex: 1 1 150px;
}
.subscriber-form-container form input[type="email"] {
  flex: 2 1 300px;
}

柔性 属性是三个物业的速记: Flex-Grow,Flex-Shrink, flex-basis. 我们想要宽度 “电子邮件” 字段是另外两个输入元素的宽度的加倍,我们通过使用它来实现这一目标 “Flex-Grow”“弯曲基础”。

“Flex-Grow” 输入元素的属性设置为 “1”, 但是电子邮件输入元素的设置为2.因此,当有额外的空间时,电子邮件输入元素将与其他输入元素相比增长两次。

FlexBox在此用例中优于网格。是的,您可以使用一些黑客来获取CSS网格使用此行为使用 米纳克斯() 功能,但FlexBox非常适合这种单一维度布局。

但是,如果您希望使用多维布局,具有维护其宽度的包装元素,例如,图像库,则网格是最佳选择:

还有一件事,你是否注意到我们没有使用任何媒体查询。那’S由于Flexbox和网格布局构建在响应性概念上,因此减少了媒体查询的使用。

 

CSS.网格将来会使Flexbox过时吗?

绝对不。

事实上,这就是这篇文章的事。 CSS.网格和FlexBox,两者都旨在解决一个不同的问题。

目前,CSS网格并未’T对浏览器有足够的支持,以制作生产准备的网站。我使用的一般拇指规则是一个功能必须涵盖超过95%的全球使用情况。只有我在真实网站中使用该功能。目前,FlexBox封面 95%的全球使用和网格封面 全球使用量的87%.

很快网格也会在浏览器中获得良好的支持,我们将使用一个网格和Flexboxes的组合来制作令人惊叹的网站布局,以前Weren’t possible.

 

特色图像 Via Depositphotos。