由于围绕 CSS Grid 的所有兴奋,我还没有看到太多关于新fr
CSS 长度单位的讨论(这里是规范)。现在浏览器对该功能的支持正在迅速提高,我认为现在是探索如何将它与我们精美的新布局引擎结合使用的时候了,因为使用它有很多好处;更清晰和可维护的代码是进行切换的主要原因。
首先,让我们看看我们通常如何看待在 CSS 中构建网格。在下面的示例中,我们创建了一个四列网格,其中每列的宽度相等:
<div class="grid">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
.grid {
display: grid;
grid-template-columns: repeat(4, 25%);
grid-column-gap: 10px;
}
如果您在属性之后从未见过该repeat()
功能,grid-template-columns
那么让我向您介绍 CSS Grid 最简洁的功能之一!从本质上讲,它是一种简写方式,可以让我们更简洁地描述重复值。我们可以改写grid-template-columns: 25% 25% 25% 25%;
,但使用repeat()
更简洁,特别是当您有更详细的宽度(如minmax()
表达式)时。
语法本质上是这样的:
repeat(number of columns/rows, the column width we want);
不过,到目前为止,我们所做的实际上存在一些问题。
首先,为了使用这个简洁的 CSS 函数,我们必须做一些数学运算。我们必须自己思考网格的总宽度 (100%) 除以我们想要的列数 (4) 是多少,这使我们达到了 25%。在这种情况下,数学非常简单,因此我们不必担心,但在更复杂的示例中,我们可以完全避免进行数学运算,让浏览器为我们计算出来。我们确实有calc()
可用的,所以我们本来可以做repeat(4, calc(100% / 4)
的,但即使这样也有点奇怪,而且还有另一个问题……
第二个问题是溢出问题。因为我们已经将每列设置为 25% 和 agrid-column-gap
到 10px,所以这会将网格元素推宽于 100%。仅仅看上面的代码,这并不是你所期望的事情的工作方式,但这就是百分比的工作方式。我们在上面的代码中真正想说的是“将每一列设置为视口宽度的 25%,并且它们之间有 10px 的间隙”。这是一个微妙的差异,但它会导致布局出现大问题。
我们在这里无意中造成了一些水平滚动:
这就是fr
单位可以帮助我们的地方。
fr
定义网格时可以使用单位(“分数”),就像定义任何其他CSS长度(例如%
、px
或em
. 让我们快速重构上面的代码以使用这个特殊的新值:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
}
这看起来与上面的示例相同,因为在本例中,我们将四列中的每一列设置为一个分数(恰好是 1/4 或 25%)。但!x 轴上不再有溢出,因为将每列设置为 1fr 会自动考虑 10px 并从每列可用的总宽度中减去它。
如果我大部分时间都能坚持百分比或像素等单位,我为什么要学习如何使用这个花哨的新 CSS 长度,你想知道吗?好吧,让我们深入研究一个更复杂的 CSS Grid 示例来解释为什么fr
它是更好的选择。在一个新的例子中,假设我们希望我们的导航在左侧,然后是一个十二列网格,应该如下所示:
对于很多 UI 来说,这是一个非常典型的场景,因此使用该fr
单元可以防止我们制作单独的网格 div 或摸索 calc。因为如果我们没有fr
在上面的示例中使用,那么我们将不得不以某种方式弄清楚以下内容:
the width of each column = ((width of viewport - width of nav) / number of columns) * 1%
这当然是可能的,阅读起来非常痛苦,如果我们改变了导航的宽度,那么我们将不得不重新进行那个愚蠢的计算。相反,该fr
单元将所有这些整理成一个超级可读的代码行:
.grid {
display: grid;
grid-template-columns: 250px repeat(12, 1fr);
grid-column-gap: 10px;
}
我们在这里所做的是为第一列设置一个以像素为单位的固定宽度,然后创建十二个单独的列,这些列设置在一个“可用空间的一部分”(字面意思是规范如何表述它)。但是没有疯狂的计算或任何东西!它非常易读,如果左侧导航的宽度发生变化,那么右侧列的宽度将自动调整。
通过一点点的工作,我们使我们的界面在未来更易于维护,并且我们确保我们的代码对于我们后面出现的下一个开发人员来说更加清晰。
来自其他人的信息
该单元的一些乐趣和力量fr
来自于将它与其他单元混合。想象一下占据其余空间的固定侧边栏和主要内容区域:grid-template-columns: 200px 1fr;
简单!
这是Alligator.io 的一个示例,很好地展示了混合单位: