CSS Masonry Layouts【一】之 multi-columns

Masonry Layouts —— 瀑布流布局,核心是一个网格布局,每行包含的内容列表的高度是不可控的,并且,每个内容列表呈堆栈状排列。称作瀑布流,最关键的是--各堆栈间没有多余的间距差(将整个布局看做一个大的容器,最新进来的内容元素,永远在高度最短的那一列上)。具体如下图所示:

注:上图是 二次元社区GACHA 的插画频道,该瀑布流插件基于NEJ,交互要求是:每一列固定宽度,根据页面大小显示不同的列,页面宽度,重排,预加载一屏,滚动加载。设计的思路是:

  1. 计算列数:根据当前页面(容器)宽度,计算一行可以排放几个元素
  2. 初始堆栈:建立列堆栈数组,用于存放各个列堆栈的高度
  3. 最小索引:得到列堆栈数组中的最小值和其对应索引
  4. 元素定位:所有元素 absolute 定位,设置后续加入元素的 top 值为列堆栈数组中的最小值,同时设置它的 left 值为该索引对应列的 left 值
  5. 更新堆栈:更新列堆栈数组中该索引下元素的值( no.4 中的 top 值加元素本身的的高度)
  • 注:上面略去了对数据的预处理(包括图片的等比缩放以及属性的二次处理等)以及滚动加载的处理过程,对于预加载一屏,由于元素高度的不可控性,只能根据瀑布流元素的平均高度行预估计,然后推算出一屏需要元素的范围,然后请求相应数量。

简化版应该是下面这样的:

但是,这样处理,表现层的东西依赖 javaScript 来处理,有点多余(当时确实是唯一的办法),能不能用样式来搞定呢?

首先,会想到 float 或者 inline-block ,但是它们都没办法很好的控制列表之间的间距。最终得到的效果就像下面这样:

那,除此之外,就没有单纯用 css 可以搞定的方法了吗?近几年,css 的技术更新频繁,出现了很多新的布局方法:multi-columnsFlexboxGrid。用上面提到的布局方法能否实现瀑布流呢?

multi-columns

multi-columns 产生之初,是用来实现文本多列排列,类似报纸、杂志的文本排列方式。multi-columns布局方式跟瀑布流的有些类似:

demo

三列:

四列:

猛一看很完美。但是,与使用 js 实现对比之下:

  • multi-columns 的元素是纵向排列的(在对元素先后次序有要求的情况下不理想)
  • 随着容器宽度变化,明显发现出现比较大的空白区域(从三列到四列)

第一个问题,multi-columns 的这种布局方式,决定了只能纵向排列;对于第二个问题:

multi-columns 简略布局思想

首先,只有在多列元素集含有块级元素、并且避免在元素内部断行并产生新列的时候,才会涉及到布局,上面的瀑布流例子,要是不避免在元素内部断行并产生新列,将会是这样的:

只有将属性 break-inside 设置为 avoid,才会有块级元素的效果。

回到上面说到的空白区域的问题,multi-columns 的整体布局会受到几个因素的影响:

总体而言,优先级:自身属性 > 容器属性。

当容器的高度小于按照 column-count 布局后的列的高度,会发生元素断裂、跨列的现象;当容器的高度大于按照 column-count 布局后的列的高度,单个列的高度会由最优布局算法生成。

所谓最优布局算法,简单来说,就是自适应:

  • 首先取 column-count ,如果元素(block)个数不超过 column-count ,布局成一横排;

  • 若是元素(block)个数超过 column-count ,首先在第一列增加 block 元素,而后以第一列的高度为标准,来填充后续各列(此时会发生列填充不满的情况);

  • 若是之后元素中发现一个高度较高的X元素,对于布局的调整会以这个较高的X元素为分界线,不会将后面的低高度元素排列到X元素之前:

就会出现较大空白区域的情况。
所以,出现空白区域的根本原因是:multi-columns 布局的特点是按列布局、顺序计算、顺序排列,前面有较大空白区域,不会用后续元素去填补。

想要具体了解 multi-columns 布局,请参考:


总结:

multi-columns 瀑布流布局,适用于:

  1. 元素不存在优先级,或者优先级要求较低
  2. 元素高度差异不明显(防止出现大片空白区域)
  3. 不兼容低版本浏览器(最重要的)

除了 multi-columnsFlexbox 以及 Grid 也可以运用到瀑布流布局中来。未完,待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值