纯CSS方式 multi-columns 方式 通过 Multi-columns 相关的属性 column-count
、column-gap
配合 break-inside
来实现瀑布流布局。
设置这样的 html 结构:
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 46 47 48 49 50 51 <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 > </div >
.masonry
是瀑布流容器,里面放置了列表 item
,在 .masonry
中设置 column-count(列数)
和 column-gap
(列间距)
item
中设置 break-inside:avoid
,这是为了控制文本块分解成单独的列,以免项目列表的内容跨列,破坏整体的布局。
在 css 中设置包裹 masonry
和 item
的属性样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 .masonry { -moz-column-count :3 ; -webkit-column-count :3 ; column-count :3 ; -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
来自适应改变列数:
1 2 3 4 5 6 7 8 9 10 @media screen and (max-width: 800px ) { .masonry { column-count: 2; // two columns on larger phones } } @media screen and (max-width: 500px ) { .masonry { column-count: 1; // two columns on larger phones } }
也是根据屏幕大小自适应改变列数
flexbox 方式 html 的结构依旧和上面的 Multi-columns 展示的一样。只是在 .masonry
容器中使用的 CSS 不一样:
在 .masonry
中是通过采用 flex-flow
来控制列,并且允许它换行。
这里关键是容器的高度,我这里要显式的设置 height
属性,当然除了设置 px
值,还可以设置100vh
,让 .masonry
容器的高度和浏览器视窗高度一样。
记住,这里height
可以设置成任何高度值(采用任何的单位),但不能不显式的设置,如果没有显式的设置,容器就无法包裹住项目列表。
1 2 3 4 5 6 7 .masonry { height : 800px ; display : flex; flex-flow : column wrap; width : 80% ; margin :2em auto; }
对于 .item,
可以不再使用 break-inside:avoid
,但其它属性可以是一样。
同样的,响应式设置,使用 Flexbox 实现响应式布局比多列布局 Multi-columns 要来得容易,他天生就具备这方面的能力,只不过我们这里需要对容器的高度做相关的处理。
前面也提到过了,如果不给 .masonry
容器显式设置高度是无法包裹项目列表的,那么这里响应式设计中就需要在不同的媒体查询条件下设置不同的高度值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @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 都是从上往下排列,不能做到从左往右排列:
img
这样子若是动态加载图片的瀑布流,体验就会很不好
我们想要的是这样:
img
这样做只能通过 js 来写瀑布流
JS方式 html 结构与上面类似,这里我用图片来做示例:
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 <div class ="masonry" > <div class ="item" > <img class ="lazy" src ="images/1.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/2.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/3.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/4.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/5.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/6.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/7.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/8.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/9.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/10.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/11.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/12.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/13.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/14.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/15.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/16.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/17.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/18.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/19.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/20.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/21.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/22.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/23.jpg" alt ="" /> </div > <div class ="item" > <img class ="lazy" src ="images/24.jpg" alt ="" /> </div > </div >
css 内容:
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 .masonry { width : 100% ; margin-top : 50px ; position :relative; } .item { z-index : 10 ; transition : 0.25s ; overflow : hidden; position : absolute; } .item img { width : 100% ; height :100% ; transition : 0.25s ; } .item :hover img { z-index : 100 ; transition : 0.25s ; overflow : hidden; animation : bounceIn 0.25s ease-in 2 alternate; } @keyframes bounceIn{ 100% { transform : scale (1.07); } }
js 瀑布流实现方式:
css 的绝对定位方式:根据每张图片的位置设置 top 和 left 值:
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 function waterFall ( ) { var pageWidth = getClient().width-8 ; var columns = 3 ; var itemWidth = parseInt (pageWidth/columns); $(".item" ).width(itemWidth); 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); if (i < columns) { $(this ).css({ top:0 , left:(itemWidth) * i }); arr.push(boxheight); } else { var minHeight = arr[0 ]; var index = 0 ; for (var j = 0 ; j < arr.length; j++) { if (minHeight > arr[j]) { minHeight = arr[j]; index = j; } } $(this ).css({ top:arr[index], left:$(".masonry .item" ).eq(index).css("left" ) }); arr[index] = arr[index] + boxheight; } }); } 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://www.cnblogs.com/ainyi/p/8766281.html