首先我们看下,什么叫瀑布流?
瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。
比如下面这个网站,便是瀑布流布局:
使用column-count和column-gap来实现瀑布流布局(适合简单的瀑布流排版)
body {
margin: 4px;
font-family: Arial, Helvetica, sans-serif;
}
.masonry {
column-count: 4;
column-gap: 0;
}
.item {
padding: 2px;
position: relative;
counter-increment: count;
}
.item img {
display: block;
width: 100%;
height: auto;
}
.item::after {
position: absolute;
display: block;
top: 2px;
left: 2px;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
background-color: #000;
color: #fff;
content: counter(count);
}
<body>
<div class="masonry">
<div class="item">
<img src="https://picsum.photos/360/460?radom=1" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/520?radom=2" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/420?radom=3" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/500?radom=4" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/420?radom=5" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/460?radom=6" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/480?radom=7" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/460?radom=8" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/420?radom=9" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/500?radom=10" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/460?radom=11" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/360/360?radom=12" alt="">
</div>
</div>
</body>
不足之处:
图片顺序是从上到下排列。如果你的网页是要按照时间倒序来展示照片,那么,我们就需要照片先从左至右排列,在换行,所以目前这种方式虽然简单,但是很多场景中不适合使用。
flexBox方式实现瀑布流布局(不推荐)
我们还是使用刚才的html格式,css布局方式改成flex布局。
关于flex布局可以看我另一篇文章:Flex布局
如果我们将flex容器的高度设置为1000px固定高度,且flex-direction设置为colunm方式,那么,当高度无法容纳所有图片时候,在flex-wrap: wrap的情况下,多余的图片变会在主轴方向换行。如下图所示:
body {
margin: 4px;
font-family: Arial, Helvetica, sans-serif;
}
.masonry {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 1000px;
}
.item {
position: relative;
width: 25%;
padding: 2px;
counter-increment: count;
}
.item img {
display: block;
width: 100%;
height: auto;
}
.item::after {
position: absolute;
display: block;
top: 2px;
left: 2px;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
background-color: #000;
color: #fff;
content: counter(count);
}
但是,这里会发现我们展示的图片排序也是自上而下的顺序排序。
但是在flex中,我们可以使用order值来改变图片顺序,从而满足有从左至右排序的要求,代码如下:
/**因为column为主轴,那么我们就规定第1,5,9张照片顺序优先,在主轴,也就是纵列先展示,
2,6,10张照片在第二列展示,以此类推,这里用了数学方式取了个巧**/
.item:nth-child(4n+1) {
order: 1;
}
.item:nth-child(4n+2) {
order: 2;
}
.item:nth-child(4n+3) {
order: 3;
}
.item:nth-child(4n+4) {
order: 4;
}
此时,网页便如图效果。
不足之处:
我们如果缩放浏览器宽度:
由于flex的容量的高度是固定的,这时候缩小容器的宽度,而容器内的图片高度又因为宽度而改变(图片宽度设置成width: 100%),这时候flex只需要分成两列,便可以容纳所有图片,而我们只是用了数学方式来取巧规定了顺序,而交叉轴宽度变小,打乱了原先布局,能那么这时候图片顺序又会被打乱。便会如上图效果。
第三方插件实现瀑布流(推荐)
在这里,我是比较推荐使用第三方插件来实现瀑布流布局的。
我这里使用masonry来举例
→→→→→masonry官网←←←←←
按照官网介绍来看下:
Masonry is a JavaScript grid layout library. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. You’ve probably seen it in use all over the Internet.
大概意思是Masonry是个第三方布局插件,让你变得像个堆砌砖墙的工匠一样,把空间里的元素放置在最佳的位置。有点难以理解吧,我们直接上代码。
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
这里我们用CDN方式引入jquery和masony插件。
下面是我写的css代码
body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
.grid-item {
position: relative;
width: 25%;
border: 2px solid hsla(0, 0%, 0%, 0.5);
box-sizing: border-box;
counter-increment: count;
}
.grid-item img {
display: block;
height: auto;
width: 100%;
}
.grid-item::after {
position: absolute;
display: block;
top: 2px;
left: 2px;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
background-color: #000;
color: #fff;
content: counter(count);
}
<body>
<div class="grid">
<!-- 第一行 -->
<div class="grid-item">
<img src="./img/1.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/2.jpg" alt="">
</div>
<div class=" grid-item">
<img src="./img/3.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/4.jpg" alt="">
</div>
<!-- 第二行 -->
<div class="grid-item">
<img src="./img/5.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/6.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/7.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/8.jpg" alt="">
</div>
<!-- 第三行 -->
<div class="grid-item">
<img src="./img/9.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/10.jpg" alt="">
</div>
<div class="grid-item ">
<img src="./img/11.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/12.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/13.jpg" alt="">
</div>
<div class="grid-item">
<img src="./img/14.jpg" alt="">
</div>
</div>
</body>
我把每个照片都宽度设置成了25%。也就是在每行会呈现4张照片。接下来是js代码
var $grid = $('.grid').masonry({
itemSelector: '.grid-item',
percentPosition: true, //使用百分比宽度的响应式布局
horizontalOrder: true, //对项目进行布局以保持水平的从左到右的顺序,定义了此条件,照片一般会按照从左到右顺序排列,但也不是绝对的。
originLeft: true, //设置布局方式为从左到右,此项是默认值,可以不填写,如果你设置值为false,则会从右到左排序
originTop: true,//设置布局方式为从上到下,此项是默认值,可以不填写,如果你设置值为false,则会从下到上排序
transitionDuration: '0.8s',//更改位置或外观时的过渡持续时间,默认是0.4s
resize:true, //调整窗口大小时自动调整元素大小和位置,此项不推荐关闭
initLayout: true,//默认为true,在初始化时候启用布局,如果设置为在初始化时禁用布局,可以在初始布局之前使用方法或添加事件,执行玩自定义方法后,在使用$grid.masonry()方法来初始化
})
//如果我initLayout: false,那么在初始化布局前,会先执行此方法,然后在调用$('.grid').masonry()方法进行初始化,下面方法只是举例
$grid.masonry( 'on', 'layoutComplete', function() {
console.log('layout is complete');
});
// 如果initLayout: true,则不需要此方法
$grid.masonry();
/** masonry的配置项一共有以下,不再多做介绍,可以自行去看英文官网。
- Recommended
- itemSelector
- columnWidth
- Layout
- Element sizing
- gutter
- horizontalOrder
- percentPosition
- stamp
- fitWidth
- originLeft
- originTop
- Setup
- containerStyle
- transitionDuration
- stagger
- resize
- initLayout
**/
设置完毕后,得到如下图的布局展示,因为我设置了horizontalOrder: true原因,所以图片排版会尽量按照从左到右方式来布局。并且因为我设置的图片宽度为百分比,所以无论是缩小和放大元素,一行都会呈现四张图片。
另外,我们也可以使用固定像素宽度来设置图片,以防图片变形。我们将图片容器的宽度从25%改为200px
.grid-item {
position: relative;
width: 200px;
border: 2px solid hsla(0, 0%, 0%, 0.5);
box-sizing: border-box;
counter-increment: count;
}
将js代码中的masonry配置项中的 percentPosition: true去除。这时候,我们得到的排版效果如下图,我们可以发现照片宽度被固定在200px,并且尽可能占满一行,无法占满则换行。
当我们缩小浏览器的宽度时候,照片会自适应宽度布局。如下图:
到这里,我们完美实现了瀑布流布局的展示。不过此插件要注意浏览器的兼容性,我在safari使用变没有生效,而chrome则没有问题。
类似的插件还有isotope等,在这里不再铺开说了,masonry也有着各种各样的布局方式,感兴趣的可以去官网看。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。