CSS布局新贵Masonry,背后标准制定藏着哪些江湖规矩?

2,691字
11–17 分钟
in

想实现Pinterest那种错落有致的瀑布流布局,以前要么用三方库,要么自己写JS一顿算。现在好了,CSS原生Masonry布局终于有了眉目。不过这事儿从2019年Firefox搞出第一个原型开始,到现在都五六年了,咋还没个准信儿?别急,这里面的门道可深了,不光是写几行代码那么简单。今天就聊聊这个Masonry布局,以及它背后那套决定CSS新特性如何诞生的“江湖规矩”。

目录

啥是Masonry布局

所谓Masonry布局,就是那种容器里的每个元素高度不一样,但它们会像砌墙一样,一个挨一个地自动填满空隙。不像Flexbox那样排成整齐的一行,也不像Grid那样必须对齐网格线。它会让短的后面紧跟着高的,充分利用空间,看着很随性但又挺规整。这玩意儿在图片墙、商品列表里特别常见,因为它能在有限宽度下展示最多内容,而且视觉上不呆板。

两套方案,两种路子

目前市面上对Masonry到底该咋实现,分成了两派,各有各的道理。

方案一:独立门派

Chrome团队搞了一套新玩法,直接给Masonry安了个新身份,用display: masonry来搞定。

.container {
  display: masonry;  /* 直接表明身份 */
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}

这套路数相当于在Flexbox和Grid之外又立了个山头。Chrome觉得Masonry的逻辑跟Grid差别太大了,Grid默认是严格对齐,而Masonry是动态填充。硬要把Masonry塞进Grid的语法里,会让开发者学一堆用不上的Grid属性,不如简单点,直接给个新属性。这种做法在Chrome 140版本里已经能体验了。

方案二:Grid亲儿子

WebKit团队(就是Safari背后的那个)提出了另一种观点,觉得Masonry压根儿就是Grid的一种特殊形式,没必要另立门户。他们搞了个item-flow属性,让Grid可以“塌缩”掉某些轨道,实现瀑布流效果。

.container {
  display: grid;  /* 还是Grid */
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  item-flow: row collapse;  /* 让行轨道塌缩,实现瀑布流 */
  gap: 1rem;
}

这么写的思路是,开发者已经熟悉Grid了,再去记一套新display值没太大必要。就像在Grid的框架里加了个开关,打开就能让元素自动填充空隙。WebKit觉得这叫“心智模型”统一,学一次Grid,很多地方都能用上。

从提案到落地,需要过几道关?

一个新CSS特性从有人提出来,到最终能在所有浏览器里用,中间得走不少流程。这事儿有点像哥几个合伙开饭馆,得有个人先提议吃什么菜,然后大家商量做法,还得有人先去厨房试试火候,最后大家都觉得好吃,才能写进菜单。

第一关:CSS工作组的圆桌会议

CSS工作组(CSSWG)是管这事儿的核心机构。这地方不是哪家浏览器公司的一言堂,而是各家代表和邀请专家一起讨论。大家得达成“共识”,才能把特性写进规范里。这就意味着,一个提案想通过,得让多数人觉得“行”,至少不反对。

这个过程会暴露很多问题。比如技术实现上有没有坑,跟以前的老代码能不能兼容,会不会让新手觉得太难。工作组得把这些都捋顺了,才敢把规范定下来。但这里有个关键点,工作组管的是“规范”,管不了浏览器“什么时候”上线。浏览器完全可以自己先推,哪怕规范还没完全确定。

第二关:浏览器的提前试水

像Chrome这次搞的display: masonry原型,就属于浏览器在规范还没完全定下来之前,先动手试试。这种做法有好处也有风险。

好处是,提前放出来,开发者能赶紧上手玩,发现一些写规范时没想到的边界情况。比如Chrome工程师在实现过程中,可能发现某些Grid的属性和Masonry放一起会打架,这些问题反馈回工作组,能让最终的规范更靠谱。这就像菜谱还没定稿,先让大厨按自己的想法做一遍,尝过之后才知道哪里要改。

风险在于,如果Chrome推得太快,其他浏览器还没跟上,那就有可能造成事实标准。万一后来工作组觉得另一个方案更好,想改,那已经写出去的代码就不好办了,得考虑老网站能不能正常显示。这里面的度很难拿捏。

第三关:开发者的呼声

整个过程里,开发者也不是吃瓜群众。GitHub上的csswg-drafts仓库就是大家提意见、看热闹、吵架的地方。任何对这个特性有想法的人,都能去那发帖,说“我觉得这个写法太复杂”或者“这个场景你们没考虑到”。

浏览器厂商也会通过自己的渠道收集反馈。比如Chrome会有技术讨论组,WebKit有邮件列表。这些反馈最终都会影响工作组的决定,毕竟规范是给人写的,不好用的话,大家就不乐意用。

这事儿现在走到哪一步了?

截止到目前,CSS工作组已经做出了一些决定,虽然过程有点曲折,但方向是有了。

Masonry最终会是一种新的布局类型,但它的名字里必须带上“grid”这个词。具体叫啥还在讨论,比如display: grid-masonry或者别的。这样既承认它是独立模型,又跟Grid有血缘关系。

工作组已经决定采纳item-flow这种方案,让Grid能通过这个属性来实现瀑布流效果。这意味着,以后写Masonry布局,大概率还是用display: grid,然后配合item-flow来开启瀑布流模式。这套路更像是给Grid加了个新功能,而不是完全重新发明一个布局方式。

当然,还有些细节没定下来。比如item-flow的缩写语法咋写,轨道列表的默认值是啥,这些还得再掰扯掰扯。但大方向是明确的,就是要在Grid的基础上,把瀑布流无缝地融合进去。

这事儿给咱啥启发?

从Masonry这个事儿能看出来,一个看似简单的CSS属性背后,有挺多看不见的博弈。这不光是技术问题,还涉及各家浏览器厂商的立场、对开发者心智模型的考量,以及对未来兼容性的责任。

以前Flexbox刚出来那会儿,情况比现在乱多了。各家浏览器实现得不一样,有的支持这个写法,有的支持那个,开发者得写各种前缀才能勉强用上。Grid吸取了Flexbox的教训,从一开始就设计得比较周全,所以普及得也快。现在Masonry站在了前人的肩膀上,讨论的问题已经不是“能不能实现”,而是“怎么实现对开发者更友好”。这本身就是一个进步。

虽然过程慢了点,但慢有慢的道理。毕竟Web标准这东西,一旦定下来,就得扛很多年。现在多讨论讨论,总比以后出了大坑再去填要好。