[译] CSS Grid Lanes 介绍


目录

原文地址:Introducing 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 中的顺序。

照片库布局演示

首先是 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)
照片演示布局,其中第 1、3、5、7 列较窄,而第 2、4、6 列宽度是其两倍。

照片库布局演示

使用 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 时,我们还可以显式放置项目。在这里,无论存在多少列,页眉始终放置在最后一列。

绘画布局——每幅画下面都有一点文字:标题等。绘画按 8 列布局。在右侧,横跨两列的是网站的页眉。

博物馆网站布局演示

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-rowsgrid-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-tolerancepack-tolerance。如果你有偏好,或者有更好名称的想法,可以在 这里发表意见。在生产网站上使用此属性之前,请留意有关最终名称的更新。

试一试

在 Safari Technology Preview 234 中试用 Grid Lanes!webkit.org/demos/grid3 上的所有演示都已使用新语法进行了更新,包括 Grid Lanes 的其他用例。不仅仅是图片!例如,充满链接的大型页脚菜单突然变得很容易布局。

15 组链接的布局。每组链接有 2 到 9 个链接——所以它们的高度各不相同。布局有五列这样的组。

大型菜单演示

.container { 
  display: grid-lanes; 
  grid-template-columns: repeat(auto-fill, minmax(max-content, 24ch)); 
  column-gap: 4lh; 
}