CSS 可以支持网格布局了,用起来超级爽
网格布局可以直接通过 CSS 实现了。
它来了,这就是网页上砌体布局的未来!经过 Mozilla 奠定的基础、苹果 WebKit 团队多年的努力,以及 CSS 工作组与所有浏览器的多轮讨论,现在它的工作原理已经很清楚了。
隆重推出 CSS 网格车道。
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
网格车道的工作原理
让我们来详细讲解一下如何创建这种经典布局。
您今天就可以在 Safari 技术预览版中体验这款照片库布局演示。
首先是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>
<!-- etc -->
</main>
首先,我们对元素应用display: grid-lanesCSS mainGrid 来创建一个网格容器,以便进行这种布局。然后,我们利用grid-template-columnsCSS Grid 的强大功能来创建“车道”。
在这种情况下,我们将使用repeat(auto-fill, minmax(250px, 1fr))至少 250 像素宽的灵活列。浏览器将决定创建多少列,并填充所有可用空间。
这样,gap: 16px通道之间就有了 16 像素的间隙,通道内的项目之间也有了 16 像素的间隙。
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
就是这样!仅用三行 CSS 代码,无需任何媒体查询或容器查询,我们就创建了一个适用于所有屏幕尺寸的灵活布局。
想象一下,就像高速公路上车水马龙,车辆首尾相接,堵得水泄不通。
就像经典的Masonry 布局一样,当浏览器决定每个元素的放置位置时,下一个元素会被放置在最靠近窗口顶部的列中。就像交通一样,每辆车都会“变换车道”,最终进入能够让它“走得最远”的车道。
这种布局使用户能够通过 Tab 键在各个栏目之间切换,访问所有当前可见的内容(而不是像以前那样,先滚动到第一列底部,然后再返回第二列顶部)。它还允许您构建一个网站,随着用户滚动页面,内容可以无限循环加载,而无需使用 JavaScript 来处理布局。
电网的力量
不同车道尺寸
因为 Grid Lanes 充分利用了 CSS Grid 的强大功能来定义车道grid-template-*,所以很容易创建出富有创意的设计变化。
例如,我们可以创建一个灵活的布局,其中窄列和宽列交替出现——即使列数随视口大小而变化,第一列和最后一列也始终是窄列。这是通过以下方式实现的grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr):
立即在 Safari 技术预览版中体验照片库布局演示。
语法蕴藏着无限可能grid-template-*。
跨项
由于我们拥有网格布局的全部功能,我们当然也可以跨越车道。
立即在 Safari 技术预览版中体验报纸文章布局演示。
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;
}
}
所有文章摘要最初都设置为占据一列。然后,第一条摘要被特别设置为占据四列,而第二条到第八条摘要则设置为占据两列。这种设计比过去十年盛行的对称式、宽度和高度都相同的布局更具动感。
放置物品
我们也可以在使用网格通道时显式地放置项目。这里,无论有多少列,标题始终位于最后一列。
立即在 Safari 技术预览版中体验博物馆网站布局演示。
main {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(24ch, 1fr));
}
header {
grid-column: -3 / -1;
}
改变方向
是的,网格通道可以双向排列!以上所有示例都创建了一种“瀑布式”布局,内容以列的形式排列。但网格通道也可以用于创建另一种方向的布局,即“砖块式”布局。
当您使用 <columns> 定义列时,浏览器会自动创建瀑布式布局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。它会根据您使用 lines 或 rows 定义了泳道,从而确定是创建列还是grid-template-columns行grid-template-rows。
CSS 工作组仍在讨论哪个属性将明确控制页面流的方向,以及它的语法是什么。争论的焦点在于是否要重用grid-auto-flow或创建新的属性,例如 grid-lanes-direction<div>。如果您有兴趣了解正在考虑的方案或发表您的看法,请参阅此讨论。
然而,由于normal无论如何都会是初始值,因此您无需等待此决定即可学习网格车道。当您只定义一个方向(grid-template-rows 即 grid-template-columns“左”)时,它就能正常工作。(如果不起作用,请检查是否grid-auto-flow设置为冲突值。unset如有必要,您可以更改它。)
位置敏感性
“容差”是为 Grid Lanes 创建的一个新概念。它允许您调整布局算法在决定放置项目位置时的精确度。
请看下一张图。注意,4 号车比 1 号车略短一些。当“容差”为零时,6 号车最终位于最右侧车道,而 7 号车则位于左侧车道。6 号车最终位于 4 号车右侧后方,因为这样它就“更靠近道路前方”(更靠近网格容器顶部)。然后,7 号车占据了下一个最靠近顶部的位置,最终位于 1 号车左侧后方。最终结果如何?第一组水平内容的顺序为 1、2、3、4,第二组为 7、5、6。
但第 1 辆车和第 4 辆车的长度差异很小。第 6 辆车的位置并没有明显更靠近页面顶部。而且,将第 6 项放在右侧,第 7 项放在左侧,可能会让用户感到意外——特别是对于那些使用 Tab 键浏览内容的用户,或者内容顺序已被标记的用户。
这些微小的尺寸差异在实际应用中无关紧要。浏览器应该将“汽车 1”和“汽车 4”这样的项目尺寸视为相同。这就是为什么默认值为 1em 的原因item-tolerance——1em这意味着在确定下一个项目的位置时,只有内容长度差异大于 1em 才会起作用。
如果您希望项目布局的移动幅度较小,可以设置更高的值item-tolerance。在下一个图中,容差设置为半辆车,这使得车辆基本从左到右排列,只有在避开超长豪华轿车时才会移动到另一条车道。现在,内容的水平分组为 1、2、3、4 和 5、6、7。
把容忍度想象成你希望司机们有多放松。他们会为了超前几英寸而变道吗?还是只有在另一条车道空间充足时才会变道?你希望他们重视多少空间,就是你设定的容忍度item-tolerance。
请记住,使用 Tab 键浏览页面时,每个项目都会在聚焦时高亮显示,而且用户可能正在使用屏幕阅读器浏览页面。项目容差设置过高会导致页面布局上下跳动,体验不佳。项目容差设置过低则会导致页面在布局中频繁跳转。请item-tolerance根据内容的尺寸和大小变化情况进行适当调整。
目前,该属性的名称item-tolerance在规范和 Safari 技术预览版 234 中均已确定。但是,该名称仍有可能更改,例如改为 <value> 或 <value> flow-tolerance之类的名称pack-tolerance。如果您有任何偏好或更好的名称建议,欢迎在此处留言。在正式网站上使用此属性之前,请密切关注最终名称的更新。
试试看
快来体验 Safari 技术预览版 234 中的网格布局吧! webkit.org/demos/grid3上的所有演示 都已更新为新语法,并新增了网格布局的其他用例。它可不只是用于图片!例如,包含大量链接的超大菜单页脚布局现在变得轻松多了。
立即在 Safari 技术预览版中体验超级菜单演示。
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(max-content, 24ch));
column-gap: 4lh;
}
接下来是什么?
CSS 工作组还有一些最后的决定需要做出。但总的来说,本文所述的功能已经准备就绪。是时候试用一下了。现在终于可以安心地记住基本语法了!
我们非常希望您能制作一些演示!展示一下您能想到哪些新的使用场景。如果您发现了任何错误或有任何改进建议,也请告诉我们。请在Bluesky或Mastodon上联系 Jen Simmons,并附上链接、评论和想法。
我们的团队自 2022 年年中以来一直在致力于此,在 WebKit 中实现并编写了 Web 标准。我们迫不及待地想看看你们会用它做出什么。