not a better man

css, 前端技术

css网格布局中auto-fill与auto-fit的不同点

css grid 布局中 我们不仅可以明确列的大小,也可以通过repeat 来重复填充子项。具体的来说,我们可以指定网格中需要多少列,然后让浏览器来处理响应性。不需要写媒体查询,我们就能够在较小的视口尺寸下显示较小的列,在较宽的屏幕空间中显示更多的列。

只需要一行css就能够做大这一点。这种神奇的、无需媒体查询的响应能力是通过repeat()函数和自动定位关键词实现的。

总而言之,repeat()函数允许我们根据需要重复列的次数。假如,我们需要创建一个12列的网格,我们可以写下面的代码。

.grid {
   display: grid;
  /* define the number of grid columns */
  grid-template-columns: repeat(12, 1fr);
}
这行代码的目的时候,将空间平均的分为12列,每列的宽度均等。每列的宽度会随空间的大小而变化。如果视口宽度比较少的话,那么列就会变的特别小。怎么解决这个问题呢。这个时候可以使用minmax()这个函数,来解决这个问题。
如下面代码所示
grid-template-columns:repeat(12, minmax(200px, 1fr));
这样我们保证了每列在小视口宽度的时候,最小宽度有200px,但是这样会导致一个问题,由于列数为12列,那么每行的知识长度有2400px,这样在视口宽度小的屏幕会导致溢出屏幕。如下视频所示:

怎么解决这个问题呢。这个时候。我们需要这两个关键字 auto-fit 或者 auto-fill。
grid-template-columns:repeat(auto-fit, minmax(250px, 1fr))

这两个关键字会告诉浏览器,当宽度不够的,无法容纳这些元素的时候,这些元素会被换行。1fr 也保证了每行的空间被充分利用。

从两个关键字的名字上来看,可能会感觉auto-fill 和auto-fit的作用是相反的,但是实际上,他们的区别相当的微妙。

fill 还是 fit,他们的不同点是什么?

在最近的一次CSS研讨会上,我对自动填充和自动拟合的区别总结如下。

auto-fill 是用尽可能多的列来填充该行。因此,只要有新的列可以容纳,它就会创建隐含的列,因为它试图用尽可能多的列来填充这一行。新添加的列可能是空的,但它们仍然会在行中占据一个指定的空间。
auto-fit是通过扩展当前可用的列,使其占据任何可用的空间,从而将其装入空间。浏览器是在用额外的列来填充额外的空间(如自动填充),然后将空的列折叠起来。

一开始听起来可能会让人困惑,但当你把这种行为可视化时,它就会变得更有意义。所以我们要做的正是这个,用Chrome DevTools的网格检查器帮助我们可视化网格项目和列的大小和位置。

我们看一下下面的demo:

这些列是用repeat()函数定义的,最小宽度为100px,最大宽度设置为1fr,这样,当有多余的空间时,它们就会展开并平均分享。至于每行的列数,我们将使用自动放置的关键字,这样我们就让浏览器来处理网格的响应性,并在需要时将列包成新的行。

在第一个例子中,浏览器将使用auto-fill关键字来放置和确定列的大小,而在第二个例子中,它将使用auto-fill。

在合适的宽度下,这两个字段都会显示相同的结果。

但它们内在的行为并不完全相同。碰巧的是,在一定的视口宽度内,从表面上看它们会产生相同的结果。

这两个关键词开始表现出不同行为的时间点取决于grid-template-columns中定义的列的数量和大小,所以它在不同的例子中会有所不同。

当视口的宽度足以容纳一个(或多个)额外的列时,这两个关键字之间的区别就很明显了。在这一点上,浏览器有两种处理方式,如何处理主要取决于是否有内容要放在额外的列中。

因此,当该行可以容纳一个新的列时,浏览器就会这样做。

“我有一些空间可以放进一个新的列。我是否有任何内容(即网格项目)可以放入这个额外的列?有吗?好的,一切顺利。我将把这一列添加到行中,在较小的视口上,它将被包裹成一个新的行。”
在没有内容可以放入新列的情况下。”我是否允许这个新列占据行中的空间(并因此影响其他行的位置和大小)? 或者我是否折叠该列并使用其空间来扩展其他列?”

自动填充和自动适应特别提供了最后一个问题的答案,并决定了浏览器应该如何处理这种情况。折叠或不折叠,这就是问题所在。而这也是答案。
你是否想让它折叠,取决于你的内容,以及你希望这些内容在响应式设计的背景下如何表现。

让我们看看这是如何运作的。为了直观地了解自动填充和自动适应的区别,看看下面的屏幕记录。我正在调整视口的大小,以创造足够的水平空间,使其能够将一个(或多个)列放入行中。请记住,这两行是相同的,并且有完全相同的内容和列数。这个演示中唯一的区别是,我对第一行使用了自动填充,对第二行使用了自动适应。

因此,当该行可以容纳一个新的列时,浏览器就会这样做。

  1. “我有一些空间可以放进一个新的列。我是否有任何内容(即网格项目)可以放入这个额外的列?有吗?好的,一切顺利。我将把这一列添加到行中,在较小的视口上,它将被包裹成一个新的行。”
  2. 在没有内容可以放入新列的情况下。”我是否允许这个新列占据行中的空间(并因此影响其他行的位置和大小)? 或者我是否折叠该列并使用其空间来扩展其他列?”

auto-fill和 auto-fit 特别提供了最后一个问题的答案,并决定了浏览器应该如何处理这种情况。折叠或不折叠,这就是问题所在。而这也是答案。
你是否想让它折叠,取决于你的内容,以及你希望这些内容在响应式设计的背景下如何表现。

在下面的视频第一个使用auto-fill 第二个使用auto-fit ,我来调整窗口大小,我们看看不同点

变动窗口大小时,auto-fill与auto-fit的不同点

从图中看到当auto-fill变大时,auto-fill的并没有充满整个窗口,我们可以打开chrom devtools 看的更清楚一些。

auto-fill的行为:“把那一行填满”。它尽可能地添加列,这个关键字并不考虑这些列是否是空的。如果容器有足够的空间来添加一列,就添加它。

auto-fit 表现有所不同,在下面的视频中可以看到。

auto-fit的表现

auto-fit :auto-fit会尽可能的占据行的空间,需要多少就扩大多少。空的列不能占据任何空间。

总结:

只有当行的宽度足以容纳更多的列时,auto-fill和auto-fit的列的大小才会有明显的区别。

如果我们使用的是auto-fit,内容将被拉伸以填满整个行的宽度。而使用auto-fill,浏览器将允许空列像它们的非空邻居一样占据行中的空间–即使它们中没有网格项,也会被分配一部分空间,从而影响后者的大小/宽度。

2 条评论

  1. 11

    如果我们使用的是auto-fill,内容将被拉伸以填满整个行的宽度。而使用auto-fill,浏览器将允许空列像它们的非空邻居一样占据行中的空间–即使它们中没有网格项,也会被分配一部分空间,从而影响后者的大小/宽度。

    最后面这段,都是使用auto-fill?

    • 由文章作者评论

      这个地方写错了,应该是 “如果我们使用的是auto-fit,内容将被拉伸以填满整个行的宽度。而使用auto-fill,浏览器将允许空列像它们的非空邻居一样占据行中的空间–即使它们中没有网格项,也会被分配一部分空间,从而影响后者的大小/宽度。” 已经修改

留下回复给 取消回复