Item Flow 第一部分:布局的新统一概念
Item Flow, Part 1: A new unified concept for layout
2025年3月28日 作者:Jen Simmons, Saron Yitbarek, Elika Etemad, Brandon Stewart
目录
- Combining Flexbox and Grid
- Item Direction
- Item Wrap
- Item Pack
- Item slack
- The Overall Plan
- What do you think?
CSS Grid 和 Flexbox 为 Web 带来了强大的布局工具,但它们尚未实现设计师可能需要的一切。 其中之一是一种流行的布局模式,称为“masonry”或“waterfall”,目前仍然需要 JavaScript 库才能实现。
CSS 中的 Masonry 布局功能最初由 Mozilla 提出,并在 Firefox 中以标志的形式实现 in 2020。 从一开始,关于这种机制就存在激烈的争论。 Apple 的 WebKit 团队接替了 Mozilla 的工作,实现了起草的规范,并将其引入 Safari Technology Preview 163。 这重新激发了对话。 到 2024 年 10 月,两种相互竞争的想法正在争论中——“Just Use Grid”或创建全新的“New Masonry Layout”。 我们在这网站上的一篇之前的文章中对此进行了广泛的介绍。
自 10 月以来发生了很多事情。 现在,第三条前进的道路正在出现——这意味着 CSS Working Group 不会选择“Just Use Grid”或“New Masonry Layout”。 它融合了两者的想法,并结合了一个全新的想法来创建一个统一的 Item Flow 属性系统。 本文解释了 Item Flow 是什么,以及它对 Flexbox 和 Grid 的影响。 在第 2 部分中,另一篇文章将更全面地解释对 Masonry 样式布局未来的影响。
但首先,为什么会出现被称为 Item Flow 的第三种可能性? 为什么不直接在“Just Use Grid”和“New Masonry Layout”选项之间进行选择? 嗯,早在 10 月,从事 Masonry 工作的人员就 要求 W3C Technical Architecture Group (TAG) 发表意见 关于这场辩论。 TAG 给出了冗长的回复,但其中最有趣的部分之一是:
总而言之,我们认为应该将 Masonry、Grid 和 Wrapping-Flexbox 纳入统一的属性集中。 Chrome 的 [New Masonry Layout] 提案过于急切地拆分属性集,但即使是 WebKit [最初由 Mozilla | Just Use Grid] 提案似乎也错过了开发更通用属性的机会。
哇。 将 Flexbox、Grid 和 Masonry 合并到统一的属性集中? 这会是什么样子?
该建议并非将所有 Flexbox 与所有 Grid 结合在一起,而是创建一组新的属性和值来“替换”专门的 flex-flow
和 grid-auto-flow
属性。 (如果您愿意,您始终可以使用较旧的语法。) 想想最初的 Alignment properties 和 gap
属性被定义为仅在一个布局系统中工作,然后稍后被修改和扩展以在多个布局上下文中工作。
我们在 Apple 的几个人聚在一起,开始研究这样一个统一的 *-flow
布局系统如何工作。 我们决定暂时将简写属性命名为 item-flow
。 这将是长手属性和值所遵循的主要属性。 总之,新规则将控制流的方向、项目如何换行、项目如何打包、布局中是否存在“slack”等等。
当我们研究细节时,我们开始感到兴奋。 突然,人们多年来一直想要的 Flexbox 和 Grid 的新功能有了一个明显的归宿。 事情似乎优雅地结合在一起。 新功能涌现:
- Flexbox 可以获得一种进行密集打包的方法
- Grid 可以获得关闭换行的能力
- 现在可以使用
item-flow
的值来触发 Masonry 布局 - 还有更多...
在本文中,我们想向您——制作网站和 Web 应用程序的人们——介绍 Item Flow,看看您的想法。 那么,让我们一起想象一下这个未来会是什么样子……
Combining Flexbox and Grid
Flexbox 有 flex-flow
。 它是以下两个长手属性的 shorthand:
flex-direction: row | row-reverse | column | column-reverse;
flex-wrap: nowrap | wrap | wrap-reverse;
Flex-direction 确定内容流动的方向,而 flex-wrap 确定是否换行内容。
CSS Grid 有 grid-auto-flow
。
grid-auto-flow: row | column | dense;
它确定内容流动的方向,以及是否使用密集打包,所有这些都在一个属性中。 它没有长手属性。
那么我们应该如何统一这些功能呢? 我们建议调用新的简写属性 item-flow
,并具有四个新的长手属性:
item-direction
item-wrap
item-pack
item-slack
(重要的是要注意,所有这些都是全新的想法。 在它们在浏览器中成为现实之前,它们将被详细讨论和更改。 为了使本文易于阅读,我们忽略了当前的争论,并且仅为每个属性/值提供一个名称,而不是列出 CSSWG 提出的所有变体。)
Item Direction
item-direction
属性将确定内容如何流动。 内容应该以行还是列流动? 正常方向还是反向方向? 这将像 flex-direction
和 grid-auto-flow
的相应部分一样工作。
item-direction: row | column | row-reverse | column-reverse
这很容易理解,因为它与我们多年使用 Flexbox 和 Grid 的期望一样。 关于“row”和“column”对于 Masonry 样式布局的含义存在争论——我们将在下一篇文章 Item Flow – Part 2: next steps for Masonry 中介绍这一点。
Item Wrap
item-wrap
属性将确定内容是否会换行,如果是,则确定换行的方向。 新的默认值将是 auto
——在 Flexbox 中解析为 nowrap
,在 Grid 中解析为 wrap
,与当前的初始值匹配。
这是一个熟悉的领域,但是创建一个新属性使我们有机会清理这些值并使它们更有意义。 我们可以添加一个新的 reverse
关键字,以便 [ nowrap | wrap ]
是一种选择,而 [ normal | reverse ]
是第二种单独的选择,从而改进了当前在 Flexbox 中的工作方式。 (为了支持遗留习惯,我们也可以保留 wrap-reverse
。) 这将给我们:
item-wrap: auto | nowrap | wrap | normal | reverse
但是 CSS Grid 以前没有 nowrap
的概念! 那么那会是什么?! 这是一个想法...
使用 Flexbox 时,有很多用例可以在一行中、一行中布局您的项目,而无需任何换行。 也许它是一个导航栏,其中每个项目都是一个不同长度的短语。 每个项目所占用的空间量由该项目的大小决定——您会得到灵活的框。
如果您想在一行中布局所有内容,但是,而是让每个项目获得相同的空间量——每个项目都是 1fr
宽? 由于列的大小是由外部决定的,因此 CSS Grid 是完成这项工作的正确工具。 但是由于 Grid 默认情况下会换行,因此开发人员通常会破解 Flexbox,而没有意识到他们今天可以使用 grid-auto-flow: column
获得所需的效果。
在具有 Item Flow 的未来,将非常明显如何使用 nowrap
告诉 Grid 将所有内容放在一行上。
.container {
display: grid;
grid-auto-columns: 1fr;
item-wrap: nowrap;
}
现在,如果有九个项目,我们将得到九列。 如果有五个项目,我们将得到五列,如下所示:
Item Pack
item-pack
属性使我们可以在不同类型的打包之间切换。
Dense packing
在 Grid 中,我们目前能够使用 grid-auto-flow: dense
切换到密集打包模式。 在新的集成系统中,可以使用 item-pack: normal | dense
来获得相同的功能——首次添加一个显式值以切换回非密集状态。
Flexbox 当前没有密集打包的概念。 那么我们可以在这里添加什么功能?
.container {
display: flex;
item-pack: dense;
}
到目前为止,已经讨论了两个想法:
- 密集打包可能意味着 Flexbox 会尝试在一行(或列)中塞入一个以上的项目,然后再开始新的一行。 它将适当地缩小该行的项目,而不是留下额外的空间并使其增长。
- 或者,要像 Grid 一样工作,密集打包可能意味着 Flexbox 会回头查看布局中以前的位置,并在任何可用空间中放置较小的项目。
为了理解这些选项的含义,让我们回顾一下 Flexbox 当前的工作方式,然后看一下 dense
可以做什么。
今天,当 Flexbox 开始布局内容时,它会用适合可用空间的项目填充一行。 当空间不足时,它会换行(如果允许换行),并填充下一行……直到所有项目都有一个归宿。 然后,它根据 flex
和 Alignment 属性分配所有额外的空间。 (请参阅插图左侧和右侧的这两个步骤。)
使用上面列出的第一个想法,Flexbox 中的密集打包可以适当地缩小项目,以便能够在一行中容纳更多项目,从而缩小每个项目而不是分配额外的空间。
使用第二个想法,为了更像 Grid 密集打包一样工作,Flexbox 可以重新排列项目的顺序,并用较小的项目反向填充较小的空间。 在这种情况下,项目 6 和 10 最终会脱离正常顺序,放置在之前的行中。
第二个想法会导致较小的项目堆积在右侧(在末端边缘)。 因此,有些人想知道这在实践中是否有用。
您希望 “dense” 对 Flexbox 意味着什么? 您更喜欢第一个还是第二个想法——或者您有第三个想法?
Balanced packing
item-pack
属性还可以允许尚不存在的新型打包。 例如,我们可以发明 item-pack: balance
。
当前,Flexbox 将项目放置在每行上,而不考虑其他行上发生的情况。 这通常会导致最后一行上的项目数量很少。
一个新的 balance
值可以告诉浏览器以某种方式平衡项目,类似于 text-wrap: balance
,确保最后一行不会显得很奇怪。
.container {
display: flex;
item-pack: balance;
}
这可能非常有用,并解决了 Flexbox 长期存在的令人沮丧的问题。
Collapsed packing
item-pack
属性还可以为我们提供 Masonry 样式布局的触发器的新位置。 这是与之前的 Masonry 提案的更改:
Proposal | Trigger for masonry layouts
---|---
Just Use Grid | grid-template-rows: collapse
New Masonry Layout | display: masonry
the Item Pack approach | item-pack: collapse
朝这个方向发展意味着我们可能不会使用 Just Use Grid 或 New Masonry Layouts 中的任何一个 masonry 布局的触发器。 我们可以放弃两者,而选择这个新的触发器。
我们将在下一篇文章 Item Flow – Part 2: next steps for Masonry 中更多地介绍 Collapsed item packing 如何用于 Masonry 布局。
Item slack
item-slack
属性允许您控制布局引擎在确定将下一个项目放置在何处时有多挑剔。
对于 Masonry 样式布局,这将是先前讨论的属性(如 grid-slack
或 masonry-slack
)的新名称。 默认 slack 为 1em
意味着,“嘿,当您寻找哪个列的顶部附近有空的空间时(在您决定将下一个项目放置在何处时),如果差异为 1em 或更小,请不要担心。 只需将它们视为并列。”
对于 Flexbox,这可以设置一个从宽松打包切换到塞入额外项目的点——当前设置为零。 1em
的值意味着,如果在 1em 的范围内,则塞入它,否则换到下一行。 这个想法可以与 Flexbox 密集打包的第一个想法(如上所述)集成,或完全替换它。
也许 -slack
不是最好的名称。 您可以在 CSSWG 问题 中建议其他单词。 例如,也许 item-tolerance
会更好——或者 threshold、strictness、adjust、sensitivity。
The Overall Plan
将所有这些想法放在一起,您将得到这个矩阵。
以防万一不清楚,Web 开发人员可以根据需要使用长手属性或简写属性。 例如,您可以使用以下方式定义 Flexbox 上下文:
.container {
display: flex;
item-direction: column;
item-wrap: nowrap;
}
或使用以下方式获得完全相同的结果:
.container {
display: flex;
item-flow: column nowrap;
}
当然,Item Flow 的整个想法仍在开发中。 仍然可以进行重大更改。 这些名称是暂时的。 本文对工作方式的描述只是初稿。 有许多对话和许多决定要做。
What do you think?
我们很想听听您对 Item Flow 的看法。
- 将
flex-flow
和grid-auto-flow
合并到一个统一的系统中是一个好主意吗? - 作为开发人员,您会使用新的语法来完成您今天使用
flex-flow
和grid-auto-flow
完成的事情吗?item-direction: row | column | row-reverse | column-reverse
item-wrap: auto | nowrap | wrap | normal | reverse
item-pack: normal | dense
- 您对于将 Flexbox 和 Grid 中的现有功能合并到统一系统中还有哪些其他想法?
- 您是否对向 Grid 和 Flexbox 添加新功能的可能性感到兴奋? 哪些功能最有潜力帮助您完成工作并解锁新的设计?
- 使用以下方式为 Grid 禁止换行:
item-wrap: nowrap
- 使用以下方式为 Flexbox 进行密集打包:
item-pack: dense
- 使用以下方式为 Flexbox 进行平衡换行:
item-pack: balance
- 使用以下方式调整何时在 Flexbox 中塞入/不塞入内容:
item-slack: <length-percentage>
- 使用以下方式为 Grid 禁止换行:
- 您还想在这个统一的系统中添加哪些其他新想法?
我们很乐意听听您的想法。 在 Bluesky 或 Mastodon 上找到 Jen Simmons,分享您的反馈。 或者更好的是,在博客文章中发表您的想法并分享链接。 探索示例。 解释想法。 并告诉我们您是否喜欢这个方向。 虽然 CSS Working Group 已决定追求 Item Flow,但如果我们听到 Web 开发人员的意见,仍然有足够的时间朝着另一个方向发展。
请继续关注 Item Flow – Part 2: next steps for Masonry,以了解有关这一切如何影响 Masonry 布局计划的更多信息,并了解有关 item-flow
语法如何工作的具体辩论的更多信息。
NextWebKit Features in Safari 18.4Learn more PreviouslyMeet Declarative Web PushLearn more