Masonry Layouts —— 瀑布流布局,核心是一个网格布局,每行包含的内容列表的高度是不可控的,而且,每一个内容列表呈堆栈状排列。称做瀑布流,最关键的是--各堆栈间没有多余的间距差(将整个布局看作一个大的容器,最新进来的内容元素,永远在高度最短的那一列上)。具体以下图所示:css
注:上图是 二次元社区GACHA 的插画频道,该瀑布流插件基于NEJ,交互要求是:每一列固定宽度,根据页面大小显示不一样的列,页面宽度,重排,预加载一屏,滚动加载。设计的思路是:html
absolute
定位,设置后续加入元素的 top
值为列堆栈数组中的最小值,同时设置它的 left
值为该索引对应列的 left 值top
值加元素自己的的高度)简化版应该是下面这样的:java
可是,这样处理,表现层的东西依赖 javaScript
来处理,有点多余(当时确实是惟一的办法),能不能用样式来搞定呢?算法
首先,会想到 float
或者 inline-block
,可是它们都没办法很好的控制列表之间的间距。最终获得的效果就像下面这样:数组
那,除此以外,就没有单纯用 css
能够搞定的方法了吗?近几年,css
的技术更新频繁,出现了不少新的布局方法:multi-columns
、Flexbox
、Grid
。用上面提到的布局方法可否实现瀑布流呢?浏览器
multi-columns
产生之初,是用来实现文本多列排列,相似报纸、杂志的文本排列方式。multi-columns
的列布局方式跟瀑布流的有些相似:ide
demo布局
三列:插件
四列:设计
猛一看很完美。可是,与使用 js 实现对比之下:
multi-columns
的元素是纵向排列的(在对元素前后次序有要求的状况下不理想)第一个问题,multi-columns
的这种布局方式,决定了只能纵向排列;对于第二个问题:
首先,只有在多列元素集含有块级元素、而且避免在元素内部断行并产生新列的时候,才会涉及到布局,上面的瀑布流例子,要是不避免在元素内部断行并产生新列,将会是这样的:
只有将属性 break-inside
设置为 avoid
,才会有块级元素的效果。
回到上面说到的空白区域的问题,multi-columns
的总体布局会受到几个因素的影响:
整体而言,优先级:自身属性 > 容器属性。
当容器的高度小于按照 column-count
布局后的列的高度,会发生元素断裂、跨列的现象;当容器的高度大于按照 column-count
布局后的列的高度,单个列的高度会由最优布局算法生成。
所谓最优布局算法,简单来讲,就是自适应:
column-count
,若是元素(block)个数不超过 column-count
,布局成一横排;column-count
,首先在第一列增长 block 元素,然后以第一列的高度为标准,来填充后续各列(此时会发生列填充不满的状况);就会出现较大空白区域的状况。
因此,出现空白区域的根本缘由是:multi-columns
布局的特色是按列布局、顺序计算、顺序排列,前面有较大空白区域,不会用后续元素去填补。
想要具体了解 multi-columns
布局,请参考:
multi-columns
瀑布流布局,适用于:
除了 multi-columns
, Flexbox
以及 Grid
也能够运用到瀑布流布局中来。未完,待续。。。