分享:纯 css 瀑布流 和 js 瀑布流

 博客地址:https://ainyi.com/60css

 

纯 css 写瀑布流

1.multi-columns 方式:

经过 Multi-columns 相关的属性 column-countcolumn-gap 配合 break-inside 来实现瀑布流布局。html

设置这样的 html 结构:git

 1             <div class="masonry"> 
 2             <div class="item"> 
 3                 <div class="item_content content-lar"> 1  4                 </div> 
 5             </div> 
 6             <div class="item"> 
 7                 <div class="item_content content-sma"> 2  8                 </div> 
 9             </div>
10             <div class="item"> 
11                 <div class="item_content content-mid"> 3 12                 </div> 
13             </div>
14             <div class="item"> 
15                 <div class="item_content content-sma"> 4 16                 </div> 
17             </div>
18             <div class="item"> 
19                 <div class="item_content content-mid"> 5 20                 </div> 
21             </div>
22             <div class="item"> 
23                 <div class="item_content content-lar"> 6 24                 </div> 
25             </div> 
26             <div class="item"> 
27                 <div class="item_content content-sma"> 7 28                 </div> 
29             </div>
30             <div class="item"> 
31                 <div class="item_content content-lar"> 8 32                 </div> 
33             </div>
34             <div class="item"> 
35                 <div class="item_content content-lar"> 9 36                 </div> 
37             </div>
38             <div class="item"> 
39                 <div class="item_content content-sma"> 10 40                 </div> 
41             </div>
42             <div class="item"> 
43                 <div class="item_content content-mid"> 11 44                 </div> 
45             </div>
46             <div class="item"> 
47                 <div class="item_content content-mid"> 12 48                 </div> 
49             </div>
50             <!-- more items --> 
51         </div>

 

.masonry 是瀑布流容器,里面放置了列表 item,在 .masonry 中设置 column-count(列数) 和 column-gap(列间距)github

item 中设置 break-inside:avoid,这是为了控制文本块分解成单独的列,以避免项目列表的内容跨列,破坏总体的布局。web

在 css 中设置包裹 masonry 和 item 的属性样式:数组

 1  .masonry { 
 2  -moz-column-count:3; /* Firefox */
 3  -webkit-column-count:3; /* Safari 和 Chrome */
 4  column-count:3;
 5  -moz-column-gap: 2em;
 6  -webkit-column-gap: 2em;
 7  column-gap: 2em;
 8  width: 80%;
 9  margin:2em auto;
10             }
11  .item { 
12  padding: 2em;
13  margin-bottom: 2em;
14  -moz-page-break-inside: avoid;
15  -webkit-column-break-inside: avoid;
16  break-inside: avoid;
17  background: #f60;
18             }

 

固然为了布局具备响应式效果,能够借助媒体查询属性,在不一样屏幕大小的条件下设置瀑布流容器 masonry 的 column-count 来自适应改变列数浏览器

 1  @media screen and (max-width: 800px) { 
 2  .masonry {  3  column-count: 2; // two columns on larger phones  4                 } 
 5  }  6  @media screen and (max-width: 500px) { 
 7  .masonry {  8  column-count: 1; // two columns on larger phones  9                 } 
10  } 

 

那么所产生的效果是:ide

也是根据屏幕大小自适应改变列数布局

 

2.flexbox 方式:

html 的结构依旧和上面的 Multi-columns 展现的同样。只是在 .masonry 容器中使用的 CSS 不同:flex

在 .masonry 中是经过采用 flex-flow 来控制列,而且容许它换行。

这里关键是容器的高度,我这里要显式的设置 height 属性,固然除了设置 px 值,还能够设置100vh,让 .masonry 容器的高度和浏览器视窗高度同样。

记住,这里height能够设置成任何高度值(采用任何的单位),但不能不显式的设置,若是没有显式的设置,容器就没法包裹住项目列表。

1  .masonry { 
2  height: 800px;
3  display: flex; 
4  flex-flow: column wrap;
5  width: 80%;
6  margin:2em auto;
7             }

 

对于 .item,能够再也不使用 break-inside:avoid,但其它属性能够是同样。

一样的,响应式设置,使用 Flexbox 实现响应式布局比多列布局 Multi-columns 要来得容易,他天生就具有这方面的能力,只不过咱们这里须要对容器的高度作相关的处理。

前面也提到过了,若是不给 .masonry 容器显式设置高度是没法包裹项目列表的,那么这里响应式设计中就须要在不一样的媒体查询条件下设置不一样的高度值:

 1  @media screen and (max-width: 1100px) { 
 2  .masonry {  3  height: 800px; 
 4                 } 
 5  }  6  @media screen and (max-width: 800px) {
 7  .masonry {  8  height: 1100px; 
 9                 } 
10  } 11  @media screen and (max-width: 600px) { 
12  .masonry { 13  height: 1300px; 
14                 } 
15  } 16  @media screen and (max-width: 460px) { 
17  .masonry { 18  height: 1600px;
19                 } 
20  } 

 

那么所产生的效果是:

也是根据屏幕大小自适应改变列数。

 

看到这里,咱们能够发现,使用纯 css 写瀑布流,每一块 item 都是从上往下排列,不能作到从左往右排列:

 

 

这样子如果动态加载图片的瀑布流,体验就会很很差

咱们想要的是这样:

 

这样作只能经过 js 来写瀑布流

 

js 写瀑布流:

html 结构与上面相似,这里我用图片来作示例:

 1         <div class="masonry"> 
 2             <div class="item"> 
 3                 <img class="lazy" src="images/1.jpg" alt="" />
 4             </div> 
 5             <div class="item"> 
 6                 <img class="lazy" src="images/2.jpg" alt="" />
 7             </div>
 8             <div class="item"> 
 9                 <img class="lazy" src="images/3.jpg" alt="" />
10             </div>
11             <div class="item"> 
12                 <img class="lazy" src="images/4.jpg" alt="" />
13             </div>
14             <div class="item"> 
15                 <img class="lazy" src="images/5.jpg" alt="" />
16             </div>
17             <div class="item"> 
18                 <img class="lazy" src="images/6.jpg" alt="" />
19             </div> 
20             <div class="item"> 
21                 <img class="lazy" src="images/7.jpg" alt="" />
22             </div>
23             <div class="item"> 
24                 <img class="lazy" src="images/8.jpg" alt="" />
25             </div>
26             <div class="item"> 
27                 <img class="lazy" src="images/9.jpg" alt="" />
28             </div>
29             <div class="item"> 
30                 <img class="lazy" src="images/10.jpg" alt="" />
31             </div>
32             <div class="item"> 
33                 <img class="lazy" src="images/11.jpg" alt="" />
34             </div>
35             <div class="item"> 
36                 <img class="lazy" src="images/12.jpg" alt="" />
37             </div>
38             <div class="item"> 
39                 <img class="lazy" src="images/13.jpg" alt="" />
40             </div>
41             <div class="item"> 
42                 <img class="lazy" src="images/14.jpg" alt="" />
43             </div>
44             <div class="item"> 
45                 <img class="lazy" src="images/15.jpg" alt="" />
46             </div>
47             <div class="item"> 
48                 <img class="lazy" src="images/16.jpg" alt="" />
49             </div>
50             <div class="item"> 
51                 <img class="lazy" src="images/17.jpg" alt="" />
52             </div>
53             <div class="item"> 
54                 <img class="lazy" src="images/18.jpg" alt="" />
55             </div>
56             <div class="item"> 
57                 <img class="lazy" src="images/19.jpg" alt="" />
58             </div>
59             <div class="item"> 
60                 <img class="lazy" src="images/20.jpg" alt="" />
61             </div>
62             <div class="item"> 
63                 <img class="lazy" src="images/21.jpg" alt="" />
64             </div>
65             <div class="item"> 
66                 <img class="lazy" src="images/22.jpg" alt="" />
67             </div>
68             <div class="item"> 
69                 <img class="lazy" src="images/23.jpg" alt="" />
70             </div>
71             <div class="item"> 
72                 <img class="lazy" src="images/24.jpg" alt="" />
73             </div>
74         </div>

 

css 内容:

 1  .masonry { 
 2  width: 100%;
 3  margin-top: 50px;
 4  position:relative;
 5             }
 6  .item { 
 7  z-index: 10;
 8  transition: 0.25s;
 9  overflow: hidden;
10  position: absolute;
11             }
12  .item img{
13  width: 100%;
14  height:100%;
15  transition: 0.25s;
16             }
17  .item:hover img{
18  z-index: 100;
19  transition: 0.25s;
20  overflow: hidden;
21  animation: bounceIn 0.25s ease-in 2 alternate;
22             }
23  @keyframes bounceIn{
24  100% { 25  transform: scale(1.07);
26                 }
27  }

 

js 瀑布流实现方式:

css 的绝对定位方式:根据每张图片的位置设置 top 和 left 值:

 1 //瀑布流效果
 2 //这里有一个坑(已经修复):
 3 //由于是动态加载远程图片,在未加载彻底没法获取图片宽高
 4 //未加载彻底就没法设定每个item(包裹图片)的top。
 5 
 6 //item的top值:第一行:top为0
 7 // 其余行:必须算出图片宽度在item宽度的缩小比例,与获取的图片高度相乘,从而得到item的高度
 8 // 就能够设置每张图片在瀑布流中每块item的top值(每一行中最小的item高度,数组查找)
 9 //item的left值:第一行:按照每块item的宽度值*块数
10 // 其余行:与自身上面一块的left值相等
11 function waterFall() { 12     // 1- 肯定图片的宽度 - 滚动条宽度
13     var pageWidth = getClient().width-8; 14     var columns = 3; //3列
15     var itemWidth = parseInt(pageWidth/columns); //获得item的宽度
16     $(".item").width(itemWidth); //设置到item的宽度
17     
18     var arr = []; 19 
20     $(".masonry .item").each(function(i){ 21         var height = $(this).find("img").height(); 22         var width = $(this).find("img").width(); 23         var bi = itemWidth/width; //获取缩小的比值
24         var boxheight = parseInt(height*bi); //图片的高度*比值 = item的高度
25 
26         if (i < columns) { 27             // 2- 肯定第一行
28             $(this).css({ 29                 top:0, 30                 left:(itemWidth) * i 31  }); 32  arr.push(boxheight); 33 
34         } else { 35             // 其余行
36             // 3- 找到数组中最小高度 和 它的索引
37             var minHeight = arr[0]; 38             var index = 0; 39             for (var j = 0; j < arr.length; j++) { 40                 if (minHeight > arr[j]) { 41                     minHeight = arr[j]; 42                     index = j; 43  } 44  } 45             // 4- 设置下一行的第一个盒子位置
46             // top值就是最小列的高度 
47             $(this).css({ 48  top:arr[index], 49                 left:$(".masonry .item").eq(index).css("left") 50  }); 51 
52             // 5- 修改最小列的高度 
53             // 最小列的高度 = 当前本身的高度 + 拼接过来的高度
54             arr[index] = arr[index] + boxheight; 55  } 56  }); 57 } 58 
59 
60 //clientWidth 处理兼容性
61 function getClient() { 62     return { 63         width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, 64         height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 65  } 66 } 67 
68 
69 
70  // 页面尺寸改变时实时触发
71 window.onresize = function() { 72     //从新定义瀑布流
73  waterFall(); 74 }; 75 
76 
77 
78 //初始化
79 window.onload = function(){ 80     
81     //实现瀑布流
82  waterFall(); 83 
84 }

 

 效果图是:

 

 

 这实现了横向排列的瀑布流效果

 

  博客地址:https://ainyi.com/60

 

欢迎浏览

GitHub:https://github.com/Krryxa

相关文章
相关标签/搜索