[译] CSS Grid Lanes 介绍
目录
Web 上瀑布流布局(Masonry Layouts)的未来已来!在 Mozilla 奠定基础、Apple WebKit 团队多年的努力以及 CSS 工作组与所有浏览器厂商进行多轮辩论之后,现在它的工作原理已经非常清晰了。
隆重介绍 CSS Grid Lanes。
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
即日起,你可以在 Safari Technology Preview 234 中尝试使用它。
Grid Lanes 如何工作
让我们详细拆解一下如何创建这种经典的布局。
首先是 HTML:
<main class="container">
<figure><img src="photo-1.jpg"></figure>
<figure><img src="photo-2.jpg"></figure>
<figure><img src="photo-3.jpg"></figure>
<!-- 等等 -->
</main>
我们首先将 display: grid-lanes 应用于 main 元素,创建一个准备好制作此类布局的 Grid 容器。然后我们需要利用 CSS Grid 的强大功能,使用 grid-template-columns 来创建 “Lanes”(泳道/轨道)。
display: grid-lanes
在这种情况下,我们使用 repeat(auto-fill, minmax(250px, 1fr)) 来创建至少 250 像素宽的灵活列。浏览器将决定创建多少列以填满所有可用空间。
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
然后,gap: 16px 给我们在泳道之间以及泳道内的项目之间提供 16 像素的间隙。
gap: 16px
完整代码如下:
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
就是这样!只需三行 CSS,无需任何媒体查询或容器查询,我们就创建了一个适应所有屏幕尺寸的灵活布局。
把它想象成拥堵交通中的高速公路。
就像经典的 Masonry 库 一样,当浏览器决定将每个项目放在哪里时,下一个项目会被放置在能让它最接近窗口顶部的列中。就像交通一样,每辆车都会“变道”,最终停在通过该车道能让它们“最靠前”的车道上。
这种布局使用户可以通过 Tab 键跨车道浏览所有当前可见的内容(而不是沿着第一列一直到底部,然后再回到第二列的顶部)。它还使你能够构建一个随着用户滚动不断加载更多内容的网站,可以无限加载,而无需 JavaScript 来处理布局。
Grid 的力量
不同的泳道尺寸 (Varying lane sizes)
因为 Grid Lanes 使用 CSS Grid 的全部能力来定义泳道(使用 grid-template-*),所以很容易创建富有创意的设计变化。
例如,我们可以创建一个具有交替窄列和宽列的灵活布局——其中第一列和最后一列始终很窄,即使列数随视口大小而变化。这是通过 grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr) 实现的。
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr)
使用 grid-template-* 语法有着无限的可能性。
跨越项目 (Spanning items)
既然我们拥有 Grid 布局的全部能力,我们当然也可以跨越泳道。
main {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(20ch, 1fr));
gap: 2lh;
}
article {
grid-column: span 1;
}
@media (1250px < width) {
article:nth-child(1) {
grid-column: span 4;
}
article:nth-child(2), article:nth-child(3), article:nth-child(4), article:nth-child(5), article:nth-child(6), article:nth-child(7), article:nth-child(8) {
grid-column: span 2;
}
}
所有的文章摘要首先设置为跨越 1 列。然后,第 1 个项目被特别指定跨越 4 列,而第 2 到第 8 个项目跨越 2 列。这创造了比典型的对称、等宽、等高布局(这种布局在过去十年中占主导地位)更具活力的图形设计。
放置项目 (Placing items)
在使用 Grid Lanes 时,我们还可以显式放置项目。在这里,无论存在多少列,页眉始终放置在最后一列。
main {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(24ch, 1fr));
}
header {
grid-column: -3 / -1;
}
改变方向 (Changing directions)
是的,泳道可以是任意方向的!上面的所有示例恰好都创建了“瀑布”形状,内容按列布局。但是 Grid Lanes 也可用于在其方向上创建布局,即“砖块”布局形状。
当你使用 grid-template-columns 定义列时,浏览器会自动创建一个瀑布布局,如下所示:
.container {
display: grid-lanes;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
如果你想要另一个方向的砖块布局,请改为使用 grid-template-rows 定义行:
.container {
display: grid-lanes;
grid-template-rows: 1fr 1fr 1fr;
}
这要归功于grid-auto-flow 的一个新默认值 normal。它会根据你使用的是 grid-template-columns 还是 grid-template-rows定义泳道,来判断是创建列还是行。
CSS 工作组仍在讨论哪个属性将显式控制流方向,以及其语法是什么。争论的焦点是重用 grid-auto-flow 还是创建像 grid-lanes-direction 这样的新属性。如果你有兴趣阅读正在考虑的选项或发表你的想法,请参阅 此讨论。
但是,由于无论哪种方式 normal 都将是初始值,你不必等待此决定即可学习 Grid Lanes。当你只定义一个方向——grid-template-rows 或 grid-template-columns——它就能直接工作(Just Work™)。(如果不行,请检查 grid-auto-flow 是否设置为冲突值。如果需要,你可以将其 unset。)
放置灵敏度 (Placement sensitivity)
“容差 (Tolerance)” 是为 Grid Lanes 创建的一个新概念。它允许你调整布局算法在决定放置项目时的挑剔程度。
想象一下,如果有两辆车,车 A 比车 B 短一点点。当“容差”为零时,即使这个微小的长度差异并不能让车 A 在视觉上明显“更靠前”,算法也会严格按照谁能排在更靠前哪怕 1 像素的位置来决定。这可能导致视觉上的顺序混乱,也就是原本应该在左边的变成在右边了,仅仅因为它能往上挤一点点。
这些微小的尺寸差异在实际意义上并不重要。相反,浏览器应该认为像车 A 和车 B 这样的项目大小是平局。这就是为什么 item-tolerance 的默认值为 1em ——这意味着在计算下一个项目去哪里时,只有大于 1em 的内容长度差异才重要。
item-tolerance: 1em;
如果你希望项目的布局更少地重新洗牌,可以为 item-tolerance 设置更高的值。
把容差想象成你希望汽车司机有多“佛系”。为了仅仅领先几英寸,他们会变道吗?还是只有在另一条车道有很大空间时才会移动?你希望他们关心的空间量就是你在 item-tolerance 中设置的量。
请记住,通过页面进行 Tab 切换的用户会在每个项目成为焦点时看到它被高亮显示,并且可能通过屏幕阅读器体验页面。设置过高的 item-tolerance 可能会导致焦点在布局中上下跳跃的尴尬体验。设置过低的 item-tolerance 可能会导致焦点在布局中不必要地来回跳跃。请根据你内容的大小和尺寸变化,将 item-tolerance 调整为合适的值。
目前,此属性在 规范 和 Safari Technology Preview 234 中名为 item-tolerance。但是,这个名称仍有可能更改,也许会变成 flow-tolerance 或 pack-tolerance。如果你有偏好,或者有更好名称的想法,可以在 这里发表意见。在生产网站上使用此属性之前,请留意有关最终名称的更新。
试一试
在 Safari Technology Preview 234 中试用 Grid Lanes!webkit.org/demos/grid3 上的所有演示都已使用新语法进行了更新,包括 Grid Lanes 的其他用例。不仅仅是图片!例如,充满链接的大型页脚菜单突然变得很容易布局。
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(max-content, 24ch));
column-gap: 4lh;
}