也许是最简单的纯CSS实现瀑布布局
效果图
瀑布流简介
瀑布流,⼜称瀑布流式布局。是⽐较流⾏的⼀种⽹站页⾯布局,视觉表现为参差不齐的多栏布局,随着页⾯滚动条向下滚动,这种布局还会不断加载数据块并附加⾄当前尾部。
以上解释还是⽐较好理解的,瀑布流⼤多时候采⽤在以图⽚为主的商品展⽰类⽹站中,⽐如:
本篇采⽤的或许是⽬前最简单的实现瀑布流的⽅式—— columns 多列布局 ,下⾯直接上代码。
CSS & HTML
.box-wrapper{
column-count: 6;
column-gap: 0;
}
.box-item{
box-sizing: border-box;
break-inside: avoid;
唱一首情歌送给我的老婆什么歌
padding: 10px;
}
.box-item > div{
height: 100%;
background: #4286F5;
box-sizing: border-box;
}
</style>
<div class="box-wrapper">
<div class="box-item">
<div></div>
</div>
<div class="box-item">
你的承诺吉他谱
<div></div>
</div>
...
</div>
代码很简单,两三个 css 属性就解决了。其中的关键属性就是 column-count ,它⽤来定义列数。column-gap 定义列的间距,它会有个默认的间距。我这⾥采⽤ padding 来设置间距,因此要将它设为 0。
你的我的在线columns 多列布局 设计的初衷应该是为了实现类似报纸上那样的多栏阅读样式,它可以将⼀⼤段⽂字折成多列。因此在这⾥,⼦元素 div 也会在⼀些随机位置被折断。瀑布流布局主要展⽰图⽚之类的,如果折断必然不好看,这⾥可以采⽤ break-inside 来避免。
break-inside CSS 属性描述了在多列布局页⾯下的内容盒⼦如何中断,如果多列布局没有内容盒⼦,这个属性会被忽略。
break-inside 有多个属性值不做赘述,这⾥采⽤ break-inside: avoid; 即可避免⼦元素被折断。
另外需要注意的是:多列布局的⼦元素⾼度⼀定要不⼀样,否则它可能会出现列数和预期的不⼀致。
区区⼏⾏ css 便能实现 参差不齐的多栏瀑布流布局 ,⽽ 不断加载数据块并附加⾄当前尾部 则必须要 js 加以实现了。
瀑布流的懒加载
实际应⽤中肯定是借助接⼝实现懒加载的数据的,这⾥为了⽅便⽤ js ⽣成数据,直接贴代码:王力宏家世
const INITIAL_NUMBER=40
const boxWrapper = document.querySelector('.box-wrapper')
function createFragment(num){
const fragment = ateDocumentFragment()
for(let i =0; i < num; i++){
const div = ateElement('div')
const randomHeight = Math.random()*400+100
div.innerHTML ='<div></div>'
div.style.height =`${randomHeight}px`
div.classList.add('box-item')
fragment.appendChild(div)
}
return fragment
}
function createLoading(){
let loading = document.querySelector('.loading')
if(!loading){
loading = ateElement('div')
loading.classList.add('loading')
}
return loading
}天凉了
function init(){
boxWrapper.appendChild(createFragment(INITIAL_NUMBER))
}
function scrollHandler(){
const{scrollTop, clientHeight, offsetHeight}= document.documentElement
const nearBottom = offsetHeight - clientHeight === scrollTop
if(nearBottom){
const num = il(Math.random()*10)+10
const fragment =createFragment(num)
const loading =createLoading()
document.body.appendChild(loading)
setTimeout(()=>{
veChild(loading)
boxWrapper.appendChild(fragment)
},1000)
}
一个人浪漫}
function debounce(callback, delay){
let timer =null
return function(){
clearTimeout(timer)
timer =setTimeout(callback, delay)
}
}
window.addEventListener('load', init)
window.addEventListener('scroll',debounce(scrollHandler,100))
</script>
滚动时判断是否触底,然后将模拟⽣成的 dom append 到⽗级中就⾏了,实现原理就这么简单 。更全更详细的代码点
缺点
多列布局实现瀑布流或许是最简单的⽅式,但是它有⼀个缺点。如果展⽰的内容需要排序或是直接就有序号的,它的排列是这样:
依照以上的排序⽅式,如果某个电商⽹站想要将热度⾼的商品排在前⾯就⾏不通了。并且随着数据的增多,它的排序会更加离谱,这就是多列布局的局限所在了。 ,我会实现⼀种类似 的布局来解决这⼀缺点。
参考