瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。
实现方式
1) 传统多列浮动。即 蘑菇街和哇哦 采用的方式
- 各列固定宽度,并且左浮动;
- 一列中的数据块为一组,列中的每个数据块依次排列即可;
- 更多数据加载时,需要分别插入到不同的列上;
- 线上例子
优点:
- 布局简单,应该说没啥特别的难点;
- 不用明确知道数据块高度,当数据块中有图片时,就不需要指定图片高度。
缺点:
- 列数固定,扩展不易,当浏览器窗口大小变化时,只能固定的x列,如果要添加一列,很难调整数据块的排列;
- 滚动加载更多数据时,还要指定插入到第几列中,还是不方便。
2) CSS3 定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#container { -webkit-column-count: 5; /*-webkit-column-gap: 10px; -webkit-column-rule: 5px solid #333; -webkit-column-width: 210px;*/ -moz-column-count: 5; /*-moz-column-gap: 20px; -moz-column-rule: 5px solid #333; -moz-column-width: 210px;*/ column-count: 5; /*column-gap: 10px; column-rule: 5px solid #333; column-width: 210px;*/ } |
- column-count 为列数; column-gap 为每列间隔距离; column-rule 为间隔边线大小; column-width 为每列宽度; 当只设置 column-width 时,浏览器窗口小于一列宽度时,列中内容自动隐藏; 当只设置 column-count 时,平均计算每列宽度,列内内容超出则隐藏; 都设了 column-count 和column-width,浏览器会根据 count 计算宽度和 width 比较,取大的那个值作为每列宽度,然后当窗口缩小时,width 的值为每列最小宽度。这边其实很简单,简易自己尝试下,详细可参考 https://developer.mozilla.org/en/CSS3_Columns 中的说明。
优点:
- 直接 CSS 定义,最方便了;
- 扩展方便,直接往容器里添加内容即可。
缺点:
- 只有高级浏览器中才能使用;
- 还有一个缺点,他的数据块排列是从上到下排列到一定高度后,再把剩余元素依次添加到下一列,这个本质上就不一样了;
- 鉴于这两个主要缺点,注定了该方法只能局限于高端浏览器,而且,更适合于文字多栏排列。
3) 绝对定位。
可谓是最优的一种方案,方便添加数据内容,窗口变化,列数/数据块都会自动调整;
缺点:
- 需要实现知道数据块高度,如果其中包含图片,需要知道图片高度;
- JS 动态计算数据块位置,当窗口缩放频繁,可能会狂耗性能。
自适应瀑布流(原生JS)
下面的这个例子是用第三种方案实现的,注释也很清楚了,应用点:本站的图片展示,美图酷览。自适应宽度,支持浏览器伸缩。具体参见demo
JS代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<script> window.onload = function() { waterFall("wrap") }//尽量避免使用Jquery的ready,safari出现问题很头痛 window.onresize = function() { waterFall("wrap") } function waterFall(element,space,children) { if(!element) return ; space = space || 20 ; children = children || "div" ; //前三行默认设置,分别为外框元素id,上下留白,子元素标签名(子元素标签名使用太多或出错) var wrap = document.getElementById(element) ; var water = wrap.getElementsByTagName(children) ; var spaceWidth = water[0].offsetWidth ; //获取子元素宽度(offsetWidth会获取块级元素的padding和border) var wrapWidth = wrap.offsetWidth ; //获取外框元素宽度 var colNum = Math.floor(wrapWidth/spaceWidth) ; //计算获取外框元素所能承受列数 var padding = Math.floor((wrapWidth - colNum*spaceWidth)/(colNum+1)) ; //计算外框元素剩余宽度并计算左右留白 var column = new Array() ; var length = water.length ; var maxHeight = 0 ; for(var i=0;i<colNum;i++) { //初始化数组来计算各列初始top值和left值 column[i] = new Array() ; column[i].top = space ; column[i].left = (spaceWidth * i)+padding*(i+1) ; //计算各列距离左侧距离 } for(var i=0;i<length;i++) { //遍历所有子元素及瀑布流布局 var index = i+1 ; //计算该子元素属于第几列 if(index%colNum==0) { sub = colNum ; } else { sub = index%colNum ; } _this = water ; _this[i].style.position = "absolute" ; _this[i].style.top = column[sub-1].top + "px" ; _this[i].style.left = column[sub-1].left + "px" ; column[sub-1].top += _this[i].offsetHeight + space ; //计算各列最新高度以便赋值 } for(var i=0;i<colNum;i++) { //获取瀑布流整体布局高度 if(column[i].top > maxHeight) maxHeight = column[i].top ; } wrap.style.height = maxHeight+"px" ; //给外框元素赋值以防止出现子元素溢出外框元素 } //希望能帮助到大家哈,我一开始使用的事Jquery,但是考虑瀑布流比较消耗浏览器内存,就改成原生javascript了,滚动到浏览器底部ajax取值做瀑布流也灭做,等到项目到了再说吧 </script> |
参考自:淘宝UED
工作中利用column布局多么?轩枫
不用,我们页面很单一,工具型页面
好的,css3的新属性除了常用的动画,转换之外你用得多的是
这的确是很不错的分享