什么是瀑布流布局,瀑布流设计

瀑布流布局怎么做(整理瀑布流相关场景多种实现方案)从体验的心

从体验的心理学角度来说,女人是不需要几个小时不停购物的生物,一望无际的瀑布就符合这种心理。瀑布的图片就像商品,就像购物扫货。只要女性继续向下伸展,就像在一个没有尽头、没有楼层高度限制的购物中心。传统布局下一页是打断,就像男朋友在他耳边低语:休息一下吧,我累了.结果不言而喻~

瀑布的缺点

缺点如下:

用户无法知道内容的总长度,也无法对内容进行宏观控制。用户无法知道自己现在在哪里,也不知道自己离目的地还有多远。回去的时候,不容易定位之前看到的东西。容易导致页面加载的负载。容易造成用户的浏览疲劳,而且没有短暂的休息时间。我是一个从事开发多年的老web前端程序员,现在辞职做自己的web前端私人量身定制课程。今年年初,我花了一个月的时间整理了一个最适合2019年学习的干货web前端学习产品。各种框架都整理好了,发给每一个前端合作伙伴。想要获取,可以关注我的头条号,后台私信我:前端免费获取。

瀑布的适用场景

根据瀑布流的优缺点,不难发现在什么情况下选择瀑布流是合理的:

当内容以图片为主时,瀑布流是更好的选择。图片占的空间很大,大脑理解的速度比文字快,有很多东西可以短时间扫描。所以用户如果使用分页显示就必须频繁翻页,会影响沉浸式体验,而瀑布流可以解决这个问题。在相对独立于信息的情况下,瀑布流是更好的选择。如果信息具有很强的相关性,用户必须做大量的回溯操作来检查之前或之后的信息。相反,如果信息相对独立,用户可以使用瀑布流同时接收来自不同地方的信息。当与搜索匹配的信息模糊时,瀑布流是更好的选择。瀑布式的直观印象是同时显示的信息与用户的搜索大致相同,而分页显示的直观印象是认为上层信息与用户的搜索相匹配。所以,当信息和搜索匹配度没有明显的区分度时,可以使用瀑布流。当用户目的性不强时,瀑布流是更好的选择。如果用户有具体信息需要查找,分页查找定位更方便,而目的性较弱时,瀑布流可以增加用户的停留时间和意外收获。多列多列布局实现瀑布流

通常,多列用于文本排序:容器{ column-count : 3;}

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

多栏布局中的子元素从上到下排列,然后从左到右排列。

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

根据这个特点,我们可以用它来实现瀑布流。

多栏瀑布流的实现主要依赖于以下属性:

Column-count:设置有多少列。column-width:设置每列的宽度,列数由总宽度和每列的宽度计算得出。column-gap:设置列间距。column-count和column-width都可以用来定义列数,没有明确的优先级。优先级的计算取决于具体的场景。

计算方法是:计算列数和列宽换算后的具体列数,以较小者为准。

图片文本的示例:

'圬工' div class='item' img src=' . '/span class='title './span/div div class=' item ' img src=' . '/span class='title './span /div!-更多项目-/分区。圬工{ column-count : 3;色谱柱-间隙: 1

0px;}.masonry .item{ border:1px solid #999; margin-bottom: 10px;}.masonry .item img{ width: 100%;}

在线Demo及完整代码地址:

效果如下:

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

我们可以看到,虽然实现了 瀑布流的效果,但奇怪的是例子中前两列的最后一个元素的 文本内容被 自动断开,一部分在当前列尾,一部分在下一列的列头。

我的理解是 multi-column布局会将其内的元素自动进行流动和平衡,尽可能保证每列的高度趋于相同,所以会将其内的文本阶段分布在两列内。

而这种展示方式无疑是我们不希望看到的,我们希望的是每个元素都是独立的,前后不断开,此时我们需要使用 break-inside来实现。

break-inside: auto | avoid

  • auto: 元素可以中断
  • avoid: 元素不能中断

修改一下之前的例子:

.masonry .item{ break-inside: avoid;}

在线Demo及完整代码地址:

效果如下:

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

效果实现了,但由于 multi-column布局中子元素的排列顺序是先 从上往下再 从左至右,所以这种方式仅适用于数据固定不变的情况,对于滚动加载更多等可动态添加数据的情况就并不适用了。

grid 布局实现瀑布流

Grid布局是最强大的 CSS 布局方案。

它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了。

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

上图这样的布局,就是 Grid 布局的拿手好戏,因此,我们就可以用 Grid来实现 瀑布流。

为实现 瀑布流先介绍以下几个属性:

  • display:设置为 grid指明当前容器为 Grid布局
  • grid-template-columns: 定义每一列的列宽
  • grid-template-rows: 定义每一行的行高
  • column-gap:用于设置列间距

grid-template-columns和 grid-template-rows,可以使用绝对单位,也可以使用百分比。并且为了表示比例关系, Grid布局提供了 fr关键字,如果设置 1fr和 2fr,表示后者是前者的两倍。

根据以上几个属性,先写一个例子出来,看看效果:

<div class="masonry"> <div class="item"></div> <!-- more items--></div>
.masonry{ display: grid; grid-template-rows: 1fr 1fr 1fr; // 分为3行 grid-template-columns: 1fr 1fr 1fr; // 分为3列 column-gap:5px; // 列间距5px}

在线Demo及完整代码地址:

效果如下:

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

我们看到高度不同的div块分布在每一个单元格内,但还没有实现 瀑布流的效果。

为实现 瀑布流再介绍几个属性:

  • grid-row-start:上边框所在的水平 网格线
  • grid-row-end:下边框所在的水平 网格线
  • grid-column-start:左边框所在的垂直 网格线
  • grid-column-end:右边框所在的垂直 网格线

那么什么是 网格线呢?

划分网格的线,称为 网格线。水平网格线划分出行,垂直网格线划分出列。

正常情况下, n行有 n+1根水平网格线, m列有 m+1根垂直网格线,比如三行就有四根水平网格线。

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

上图是一个 4 x 4 的网格,共有5根水平网格线和5根垂直网格线。

这4个属性可接收如下属性:

  • auto:表示自动放置
  • 自定义名称:可以给予网格线一个名称,并在此处引用(本文并不涉及)
  • 网格线索引: 代表第几条网格线(从1开始)
  • span+数字 : 表示上下边框或左右边框跨越多少网格

来看看这个 网格线用处

为方便查看,我们让例子中的每个div块高度修改为100%,并将样式代码修改为:

.item{ height:100%;}.item:first-child{ grid-row-start:1; grid-row-end:span 2;}

在线Demo及完整代码地址:

效果如下:

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

我们对 Grid布局中的第一项添加了 grid-row-start:1和 grid-row-end:span2,令其上边框位于1水平网格线,下边框距上边框跨越2个水平网格线。从效果上看来,是不是有点像 瀑布流了呢!

在之前的例子中,我们分别指定了 grid-template-columns和 grid-template-rows用于定义几行几列,由于行列数的确定,其内的每个单元格的宽高也被确定了,而实际的 瀑布流布局中,宽度是固定的,而高度是动态的,并且具体的行数也是无法在开始时确定的,所以我们需要在 Grid布局中不指定行高(grid-template-rows)。

介绍另一个属性:

grid-auto-rows:用来设置多余网格的行高

结合刚才说的Grid实现的瀑布流布局中,不设置行高(grid-template-rows),此时设置 grid-auto-rows后,所有单元格的高度均为 grid-auto-rows指定的值。

由于 grid-row-start和 grid-row-end可以指定单元格的上边距和下边距位置,也就是说可以将单元格的高度拉伸,而原有高度由 grid-auto-rows决定,我们仅需将 grid-auto-rows设置一个很小的值,比如 10px,然后对其进行拉伸将其高度指定为真实高度,每一个单元格都做如下操作,那么瀑布流就实现了~

假设第一个单元格内容真实高度为100px,由于 grid-auto-rows:10px,那么我们可以这样设置:

.item1{ grid-row-start:'auto'; grid-row-end:span 10;}

假设第二个单元格内容真实高度为150px,由于 grid-auto-rows:10px,那么我们可以这样设置:

.item2{ grid-row-start:'auto'; grid-row-end:span 15;}

当然了,在实际情况中, 瀑布流更多的是为图片的展示而服务的,并且由于图片是异步请求加载,只有在加载完成后才能获取图片的真实宽高,所以不得不使用JS来动态将单元格高度进行拉伸。

伪代码如下:

 //image-dom let img = document.getElementsByTagName('img')[0]; //image-dom 当前宽度 let width = img.width;
 let image = new Image(); image.src = 'xxxx.img'; image.onload = function(){ //图片原宽 let w = image.width; //图片原高 let h = image.height; //image-dom的真实高度(依据当前宽度及图片真实宽高) let height = Math.round(h * width / w) //设置当前跨越几个网格(每个网格10px) img.style.gridRowEnd = `span ${~~(height/10)}` }

在线Demo及完整代码地址:

效果如下:

「前端进阶」干货!深度解析瀑布流布局
「前端进阶」干货!深度解析瀑布流布局

Flexbox 实现瀑布流

Flexbox布局到今天已经是使用非常广泛的,也算是很成熟的一个特性。在此就不再介绍 Flexbox布局的相关内容,如果还有不是很了解的朋友,可参见阮一峰的《Flex 布局教程:语法篇》(http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html)

那接下来我们就看 Flexbox怎么实现瀑布流布局。

此时,我们需要将html结构设计成如下结构:

<div class="masonry"> <!-- 第一列 --> <div class="column"> <div class="item"></div> <!-- more items--> </div> <!-- 第二列 --> <div class="column"> <div class="item"></div> <!-- more items--> </div> <!-- 第三列 --> <div class="column"> <div class="item"></div> <!-- more items--> </div></div>

上面代码中 div.masonry代表当前瀑布流容器, div.column代表每一列的容器, div.item代表每一列中的每一项。

我们需要将 div.masonry和 div.column都通过 display:flex将其设置为 Flex容器。

不同的是 瀑布流容器主轴方向设置为水平方向 flex-direction:row, 列容器主轴方向设置为垂直方向 flex-direction:column

.masonry { display: flex; // 设置为Flex容器 flex-direction: row; // 主轴方向设置为水平方向}
.column { display: flex; // 设置为Flex容器 flex-direction: column; // 主轴方向设置为垂直方向}

由于当前的html结构分为了 瀑布流容器和 列容器,并且常见的需求图片均是 从左至右再 从上到下来进行排列,所以需要通过 Javascript来区分每一列的具体数据:

假设分为三列,伪代码如下:

let data1 = [], //第一列 data2 = [], //第二列 data3 = [], //第三列 i = 0;while (i < data.length) { data1.push(data[i++]); if (i < data.length) { data2.push(data[i++]); } if (i < data.length) { data3.push(data[i++]); }}return { //第一列 data1, //第二列 data2, //第三列 data3};

在线Demo及完整代码地址:

总结

做瀑布流需要考虑几方面大因素,图片质量,图片大小,加载速度,如果这些不能同时满足,会大大降低用户体验。个人觉得瀑布流对于触屏终端体验会更好一些。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/175116.html

(0)

相关推荐