分享:纯 css 瀑布流 和 js 瀑布流
博客地址:https://ainyi.com/60
纯 css 写瀑布流
1.multi-columns 方式:
通过 Multi-columns 相关的属性 column-count、column-gap 配合 break-inside 来实现瀑布流布局。
设置这样的 html 结构:
<div class="masonry">
<div class="item">
<div class="item_content content-lar"> 1
</div>
</div>
<div class="item">
<div class="item_content content-sma"> 2
</div>
</div>
<div class="item">
<div class="item_content content-mid"> 3
</div>
</div>
<div class="item">
<div class="item_content content-sma"> 4
</div>
</div>
<div class="item">
<div class="item_content content-mid"> 5
</div>
</div>
<div class="item">
<div class="item_content content-lar"> 6
</div>
</div>
<div class="item">
<div class="item_content content-sma"> 7
</div>
</div>
<div class="item">
<div class="item_content content-lar"> 8
</div>
</div>
<div class="item">
<div class="item_content content-lar"> 9
</div>
</div>
<div class="item">
<div class="item_content content-sma"> 10
</div>
</div>
<div class="item">
<div class="item_content content-mid"> 11
</div>
</div>
<div class="item">
<div class="item_content content-mid"> 12
</div>
</div>
<!-- more items -->
</div>
.masonry 是瀑布流容器,里面放置了列表 item,在 .masonry 中设置 column-count(列数) 和 column-gap(列间距)
item 中设置 break-inside:avoid,这是为了控制文本块分解成单独的列,以免项目列表的内容跨列,破坏整体的布局。
在 css 中设置包裹 masonry 和 item 的属性样式:
.masonry {
-moz-column-count:; /* Firefox */
-webkit-column-count:; /* Safari 和 Chrome */
column-count:;
-moz-column-gap: 2em;
-webkit-column-gap: 2em;
column-gap: 2em;
width: 80%;
margin:2em auto;
}
.item {
padding: 2em;
margin-bottom: 2em;
-moz-page-break-inside: avoid;
-webkit-column-break-inside: avoid;
break-inside: avoid;
background: #f60;
}
当然为了布局具有响应式效果,可以借助媒体查询属性,在不同屏幕大小的条件下设置瀑布流容器 masonry 的 column-count 来自适应改变列数:
@media screen and (max-width: 800px) {
.masonry {
column-count:; // two columns on larger phones
}
}
@media screen and (max-width: 500px) {
.masonry {
column-count:; // two columns on larger phones
}
}
那么所产生的效果是:

也是根据屏幕大小自适应改变列数
2.flexbox 方式:
html 的结构依旧和上面的 Multi-columns 展示的一样。只是在 .masonry 容器中使用的 CSS 不一样:
在 .masonry 中是通过采用 flex-flow 来控制列,并且允许它换行。
这里关键是容器的高度,我这里要显式的设置 height 属性,当然除了设置 px 值,还可以设置100vh,让 .masonry 容器的高度和浏览器视窗高度一样。
记住,这里height可以设置成任何高度值(采用任何的单位),但不能不显式的设置,如果没有显式的设置,容器就无法包裹住项目列表。
.masonry {
height: 800px;
display: flex;
flex-flow: column wrap;
width: 80%;
margin:2em auto;
}
对于 .item,可以不再使用 break-inside:avoid,但其它属性可以是一样。
同样的,响应式设置,使用 Flexbox 实现响应式布局比多列布局 Multi-columns 要来得容易,他天生就具备这方面的能力,只不过我们这里需要对容器的高度做相关的处理。
前面也提到过了,如果不给 .masonry 容器显式设置高度是无法包裹项目列表的,那么这里响应式设计中就需要在不同的媒体查询条件下设置不同的高度值:
@media screen and (max-width: 1100px) {
.masonry {
height: 800px;
}
}
@media screen and (max-width: 800px) {
.masonry {
height: 1100px;
}
}
@media screen and (max-width: 600px) {
.masonry {
height: 1300px;
}
}
@media screen and (max-width: 460px) {
.masonry {
height: 1600px;
}
}
那么所产生的效果是:

也是根据屏幕大小自适应改变列数。
看到这里,我们可以发现,使用纯 css 写瀑布流,每一块 item 都是从上往下排列,不能做到从左往右排列:

这样子若是动态加载图片的瀑布流,体验就会很不好
我们想要的是这样:

这样做只能通过 js 来写瀑布流
js 写瀑布流:
html 结构与上面类似,这里我用图片来做示例:
<div class="masonry">
<div class="item">
<img class="lazy" src="data:images/1.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/2.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/3.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/4.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/5.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/6.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/7.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/8.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/9.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/10.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/11.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/12.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/13.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/14.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/15.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/16.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/17.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/18.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/19.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/20.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/21.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/22.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/23.jpg" alt="" />
</div>
<div class="item">
<img class="lazy" src="data:images/24.jpg" alt="" />
</div>
</div>
css 内容:
.masonry {
width: 100%;
margin-top: 50px;
position:relative;
}
.item {
z-index:;
transition: 0.25s;
overflow: hidden;
position: absolute;
}
.item img{
width: 100%;
height:100%;
transition: 0.25s;
}
.item:hover img{
z-index:;
transition: 0.25s;
overflow: hidden;
animation: bounceIn 0.25s ease-in 2 alternate;
}
@keyframes bounceIn{
100% {
transform: scale(1.07);
}
}
js 瀑布流实现方式:
css 的绝对定位方式:根据每张图片的位置设置 top 和 left 值:
//瀑布流效果
//这里有一个坑(已经修复):
//因为是动态加载远程图片,在未加载完全无法获取图片宽高
//未加载完全就无法设定每一个item(包裹图片)的top。 //item的top值:第一行:top为0
// 其他行:必须算出图片宽度在item宽度的缩小比例,与获取的图片高度相乘,从而获得item的高度
// 就可以设置每张图片在瀑布流中每块item的top值(每一行中最小的item高度,数组查找)
//item的left值:第一行:按照每块item的宽度值*块数
// 其他行:与自身上面一块的left值相等
function waterFall() {
// 1- 确定图片的宽度 - 滚动条宽度
var pageWidth = getClient().width-8;
var columns = 3; //3列
var itemWidth = parseInt(pageWidth/columns); //得到item的宽度
$(".item").width(itemWidth); //设置到item的宽度 var arr = []; $(".masonry .item").each(function(i){
var height = $(this).find("img").height();
var width = $(this).find("img").width();
var bi = itemWidth/width; //获取缩小的比值
var boxheight = parseInt(height*bi); //图片的高度*比值 = item的高度 if (i < columns) {
// 2- 确定第一行
$(this).css({
top:0,
left:(itemWidth) * i
});
arr.push(boxheight); } else {
// 其他行
// 3- 找到数组中最小高度 和 它的索引
var minHeight = arr[0];
var index = 0;
for (var j = 0; j < arr.length; j++) {
if (minHeight > arr[j]) {
minHeight = arr[j];
index = j;
}
}
// 4- 设置下一行的第一个盒子位置
// top值就是最小列的高度
$(this).css({
top:arr[index],
left:$(".masonry .item").eq(index).css("left")
}); // 5- 修改最小列的高度
// 最小列的高度 = 当前自己的高度 + 拼接过来的高度
arr[index] = arr[index] + boxheight;
}
});
} //clientWidth 处理兼容性
function getClient() {
return {
width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
} // 页面尺寸改变时实时触发
window.onresize = function() {
//重新定义瀑布流
waterFall();
}; //初始化
window.onload = function(){ //实现瀑布流
waterFall(); }
效果图是:

这实现了横向排列的瀑布流效果
博客地址:https://ainyi.com/60
欢迎浏览
GitHub:https://github.com/Krryxa
分享:纯 css 瀑布流 和 js 瀑布流的更多相关文章
- 关于瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式.即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置. 为什么使用瀑 ...
- 【js】【图片瀑布流】js瀑布流显示图片20180315
js实现把图片用瀑布流显示,只需要“jquery-1.11.2.min.js”. js: //瀑布流显示图片 var WaterfallImg = { option: { maxWidth: 850, ...
- 纯CSS 箭头流程,网上找的,留着备用
无意之中看到一个纯CSS做的箭头导航(流程式),收藏一下,以备不时之需 实际效果 步骤一 步骤二 步骤三 步骤四 源代码: HTML: <div class="wrapper" ...
- CSS定位与布局:普通流
CSS定位与布局属于CSS的基础,也是CSS布局影响很大的一部分,具体主要包括三种定位与布局机制( Positioning schemes):普通流,浮动,绝对定位. 其实除了这三种之外,还有一些定位 ...
- 纯 CSS 实现幻灯片播放
介绍: 今日看到一道面试题,关于 使用纯CSS,不利用js, 写一个简单的幻灯效果页面.于是做了一个小demo,建议使用chrome,IE11查看~~ 主要思想: 利用 CSS3的 伪类选择器 : ...
- 详解纯css实现瀑布流(multi-column多列及flex布局)
瀑布流的布局自我感觉还是很吸引人的,最近又看到实现瀑布流这个做法,在这里记录下,特别的,感觉flex布局实现瀑布流还是有点懵的样子,不过现在就可以明白它的原理了 1.multi-column多列布局实 ...
- 纯css实现瀑布流(multi-column多列及flex布局)
瀑布流的布局自我感觉还是很吸引人的,最近又看到实现瀑布流这个做法,在这里记录下,特别的,感觉flex布局实现瀑布流还是有点懵的样子,不过现在就可以明白它的原理了 1.multi-column多列布局实 ...
- 瀑布流的实现纯CSS实现Jquery实现
瀑布流的实现 注:本文部分图片自百度下载,如有侵权,联系删图. 首先,选择几张图片布局到HTML内容中.HTML如下所示. <div class="wrapper"> ...
- 面向对象js瀑布流效果
index.html <!doctype html><html lang="en"> <head> <!--网站编码格式,UTF-8 国 ...
随机推荐
- node.js-v6新版安装过程
1.Node.js简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用 ...
- mybatis-spring整合
1. 配置jar包 Spring,mybatis,mybatis-spring,mysql等... <properties> <project.build.sourceEncodin ...
- LOOKUP函数入门
2018-02-11 作者:ExcelHome 阅读:22045次 转载请注明来源"ExcelHome"并保留原文链接.固定链接:http://www.excelh ...
- Linux Centos 下安装软件 三种方式(转)
Linux学习的路还很远呢,各位码农,新年快乐哈! 1)一种是软件的源代码,您需要自己动手编译它.这种软件安装包通常是用gzip压缩过的tar包(后缀为.tar.gz). 2)另一种是软件的可执行程序 ...
- NEO从入门到开窗(1) - 一个智能合约的诞生
一.啰嗦两句 最近一直都在研究区块链,BitCoin,Etherenum, Hyper Ledger Fabric还有今天的主角小蚂蚁,当然出名以后改了一个艺名叫NEO.区块链大部分都是用Golang ...
- Cesium 一个导致浏览器内存一直增长的方法
为了实时更改模型的位置,给模型附上ID,后面判断如果传来的数据中没有已经创建的模型,删掉该模型时用到方法:viewer.entities.removeById(modelId);和viewer.ent ...
- 用C#开发的一个通用的地铁换乘查询工具
日常生活中,上班下班坐地铁已经是常事,每当我想去某一个远一点的地方,如果有地铁首选就是地铁,因为方便嘛!每次坐地铁,我们都是凭肉眼去得出我们心中最佳的换乘方案,但是,如果对于线路较少的城市来说,这个方 ...
- 云服务器Windows Server2012 配置http服务器(又称Web服务器,IIS)
出错:无法打开运行空间池.服务器管理器WinRM插件可能已损坏或丢失. 解决方法: http://shiyousan.com/post/636308065767125916 第一步是开启WinRM服务 ...
- [日常] Codeforces Round #440 Div.2 大力翻车实况
上次打了一发ABC然后大力翻车...上午考试又停电+Unrated令人非常滑稽...下午终于到了CF比赛... 赛前大力安利了一发然后拉了老白/ $ljm$ / $wcx$ 一起打, 然后搞了个 TI ...
- 实验MyOD
实验MyOD 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 提交测试代码和运行结果截图,加上学号水印,提交码云代码链接. 代码如下: (刚开始 ...