使用JS或CSS如何实现瀑布流布局,几种方案介绍

本篇文章带大家了解一下瀑布流布局,介绍一下三种靠谱js方案,以及n种不靠谱css方案。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

使用JS或CSS如何实现瀑布流布局,几种方案介绍

本着实用精神,我们今天来分享一下瀑布流布局昨天有个小兄弟问我怎么做,我找了半天没找到,啊原来写在内网了)。

演示地址: http://www.lilnong.top/static/html/waterfall.html

瀑布流布局是什么?

比如说 花瓣网蘑菇街 (我下面贴图了), 这些网站在显示内容的时候就使用了瀑布流布局。

我们也想做一个展示我们设计稿(定宽,不定高)的页面,瀑布流是很棒的一种方案。

立即学习“前端免费学习笔记(深入)”;

瀑布流布局其核心是基于一个网格的布局,而且每行包含的项目列表高度是随机的(随着自己内容动态变化高度),同时每个项目列表呈堆栈形式排列,最为关键的是,堆栈之间彼此之间没有多余的间距差存大。还是上图来看看我们说的瀑布流布局是什么样子。

网站 蘑菇街 花瓣网 京东 VV

截图@@##@@@@##@@@@##@@@@##@@方案分通道absolute

grid、inline、float 魔性方案

也算是纯 CSS 方案吧,本质上来讲是依赖文档流,从左到右,从上到下。

方案 grid inline float bootstrap-grid

截图@@##@@@@##@@@@##@@@@##@@

可以看到在文档流布局中有非常明显的的概念,当一个行被撑开就会留下空白,行与行不会重叠。这里最魔性的就是 float 布局了。

DOM 结构

div.list     // 设置 gird 或者 block,注意清除浮动  div.item   // 设置为 inline 或者 float,使其能流动    img      // 设置定宽,高度自适应,间距等。

grid 方案说明

.wrap-waterfall--grid img{vertical-align: top;width: 100px}.wrap-waterfall--grid .list{    display: grid;    grid-gap: 10px;    /* 可以看到,网格大小,占据位置是需要提前设定的 */    grid-template-columns: repeat(4, 1fr);    grid-auto-rows: minmax(50px, auto);}

grid 在某些情况下会比 flex 好用。比如说需要突破行的限制,但是只适用于固定布局,如下图的布局,如果不使用grid你会如何实现呢?

1.png

网传有 gird 实现瀑布流布局的方案,但是我看了几个他们不是色块,就是图片变形、裁剪,方案是用 nth-child 定高,太恐怖了吧

columns、flex CSS实现 不靠谱方案

也是纯 CSS 方案,相比较上面的方案而言,方案已经可以接受,只是还有部分问题。

顺序是先垂直,后水平(columns)兼容性问题(flex)需要给一个固定高度,会出现超出设定列,以及无法充满设定列。

方案 columns flex

截图@@##@@@@##@@

columns 方案

天生支持,只需要给父级设置即可 columns: 4; column-gap: 6px;

flex 方案

flex-flow: column wrap;height: 2300px; 默认情况下是水平排列,通过修改为垂直排列并且允许换行,之后把通过固定高度使内容换行。

absolute、通道 高度计算方案 靠谱方案

方案 absolute 取余分通道 计算高度分通道

头部截图@@##@@@@##@@@@##@@

这里的方案就靠谱起来了,可以满足我们使用要求。

我们来回忆一下我们的需求:展示一些内容,内容有特性定宽,不定高。不定高一般是因为内容长度或者高度不一致导致的,常见内容又分为两种文字和图片

文字的话,在没有异步字体的情况下,可以理解为同步就可以获取到盒子高度。

图片的话,因为加载是异步的,所以获取盒子的真实高度也是异步的。但是这里一般分为两种情况

无高度,那么可以通过onload来监听图片加载完成。等图片加载完成再去获取高度。

有高度,这种方案一般用在封面图、或者文章中,在上传图片的时候会保存原图尺寸,这个时候我们就可以直接使用已有数据。

获取图片高度

// 用于获取图片的真实高度naturalHeight: 1180// 用于获取图片的真实宽度naturalWidth: 1200//用户获取图片当前的渲染高度(会受 css 影响)height: 98//用户获取图片当前的渲染宽度(会受 css 影响)width: 100// 可返回浏览器是否已完成对图像的加载。如果加载完成,则返回 true,否则返回 fasle。complete 属性// 可以监听到图片加载完成的动作onload

基于上面的内容,那我们可以先判断 complete 属性,

function getImageSize(img){    if(img.complete){        return Promise.resolve({            naturalHeight: img.naturalHeight,            naturalWidth: img.naturalWidth,            height: img.height,            width: img.width,        })    }else{        return new Promise((resolve, reject)=>{            img.addEventListener('load', ()=>{                resolve({                    naturalHeight: img.naturalHeight,                    naturalWidth: img.naturalWidth,                    height: img.height,                    width: img.width,                })            })        })    }}/*// 测试用例el = document.createElement('img');el.src = 'http://cors-www.lilnong.top/favicon.ico?'+Math.random()getImageSize(el).then(console.log).catch(console.error)setTimeout(()=>getImageSize(el).then(console.log).catch(console.error), 1000)*/

absolute 计算高度方案

因为普通的布局已经无法满足我们的需求,所以我们可以考虑通过 position: absolute 来使内容通过绝对定位来显示

核心操作就是维护每个元素的 left、top,然后使用 left 和 top 去渲染到正确位置。

getListPosition(){    // 视口宽度 / 每列宽度 得出划分为几列    let col = this.screenWidth / this.itemWidth >> 0;    var arr = [];    for(var i = 0; i {        // 找到最低的一列        var colIndex = 0;        for(var i = 1; i  arr[i].height){                // colItem = arr[i]                colIndex = i            }        }        // 修改元素的信息        // 所属列        item.line = colIndex;        // 计算之后的 top 距离        item.top = arr[colIndex].height+ 'px';        // 计算之后的 left 距离        item.left = colIndex * (this.itemWidth + 10) + 'px'        // 累加操作        arr[colIndex].list.push(item);        arr[colIndex].height += item.height + 10;    })    return arr},

通过计算,我们可以到,瀑布流布局下每个元素的位置,通过绝对定位就可以实现。

根据下标,来渲染到不同的通道 idx % 4

因为上个方案用到了绝对定位,那么有没有不用绝对定位的方案呢?回到我们的问题点上 定宽,不定高,那我们完全可以通过分开渲染放弃 absolute 来实现。

jsGroupList(){    return this.list.reduce((s,n,idx)=>{        // 根据下标,直接分配所属列        s[idx % 4].push({idx: idx, item: n})        return s    }, [[],[],[],[],])},

看开头是实现类似的功能的,但是有一个弊端(快来评论区回复呀)。

通过高度计算,然后分通道,避免 absolute

因为上一个方案是按下标分类的,其实瀑布流是按高度分类的,所以我们分类条件换成最低的列。

jsGroupHeightList(){    var list = [        {height: 0, list: []},{height: 0, list: []},        {height: 0, list: []},{height: 0, list: []},    ]    // 遍历每个元素    for(var i = 0; i {            if(v.height < minHeightItem.height) minHeightItem = v        })        // 把新的元素高度累加到列中。        minHeightItem.height += this.listInfo[i].height        // 把新的元素push到列中        minHeightItem.list.push({idx: i, item: this.list[i]})    }    return list;},

总结

好了,到这里我能想到的方案就都介绍了。你还有什么方案吗?咱们可以在评论区讨论一下可行性。接下来就是我们的方案总结了。

方案 优点 缺点 点评

columns实现简单、纯 CSS 方案兼容性-flex-需要固定高度,填充难以控制等问题-float、inline、bootstrapGrid–没点大都用不出这方案grid–可以nth-child模拟实现、或者等待兼容性 masonryabsolute效果好-JS计算无限可能js普通通道-填充难以控制-js优化通道效果好、无绝对定位在出现夸列等操作的时候不是很好控制-

更多编程相关知识,请访问:编程入门!!

2.png3.png4.png5.png6.png7.png8.png9.png10.png11.png12.png13.png14.png

以上就是使用JS或CSS如何实现瀑布流布局,几种方案介绍的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1620907.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
css怎么写五角星
上一篇 2025年12月24日 07:19:39
CSS选择器学习之聊聊复合选择器(详细介绍)
下一篇 2025年12月24日 07:19:57

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    000
  • css max-height属性怎么用

    max-height 属性设置元素的最大高度。 说明 该属性值会对元素的高度设置一个最高限制。因此,元素可以比指定值矮,但不能比其高。不允许指定负值。 注意:max-height 属性不包括外边距、边框和内边距。 立即学习“前端免费学习笔记(深入)”; 值描述none 默认。定义对元素被允许的最大高…

    2026年5月10日
    100
  • 修复点击时按钮抖动:CSS垂直对齐实践

    本文探讨了在Web开发中,交互式按钮(如播放/暂停按钮)在点击时发生意外垂直位移的问题。通过分析CSS样式变化对元素布局的影响,我们发现这是由于按钮不同状态下的边框样式和内边距改变,以及默认的垂直对齐行为共同作用所致。核心解决方案是利用CSS的vertical-align属性,将其设置为middle…

    2026年5月10日
    000
  • 使用 Jupyter Notebook 进行探索性数据分析

    Jupyter Notebook通过单元格实现代码与Markdown结合,支持数据导入(pandas)、清洗(fillna)、探索(matplotlib/seaborn可视化)、统计分析(describe/corr)和特征工程,便于记录与分享分析过程。 Jupyter Notebook 是进行探索性…

    2026年5月10日
    000
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    000
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    100
  • HTML5网页如何实现手势操作 HTML5网页移动端交互的处理技巧

    首先利用原生touch事件实现滑动判断,再通过preventDefault解决滚动冲突,接着引入Hammer.js处理复杂手势,最后通过优化点击区域、避免事件冲突和增加视觉反馈提升体验。 在移动端浏览器中,HTML5网页可以通过触摸事件实现手势操作,提升用户体验。虽然原生JavaScript提供了基…

    2026年5月10日
    000
  • JavaScript 闭包:理解闭包原理与内存泄漏问题

    闭包是函数访问其外部作用域变量的能力,即使外部函数已执行完毕。如 inner 函数引用 outer 中的 count,形成闭包,使变量持久存在。闭包本身无害,但可能因延长变量生命周期导致内存泄漏,例如事件监听器引用大对象时。若未及时清理 DOM 事件或定时器,闭包会阻止垃圾回收,造成内存占用过高。解…

    2026年5月10日
    000
  • JavaScript 动态菜单点击高亮效果实现教程

    本教程详细介绍了如何使用 JavaScript 实现动态菜单的点击高亮功能。通过事件委托和状态管理,当用户点击菜单项时,被点击项会高亮显示(绿色),同时其他菜单项恢复默认样式(白色)。这种方法避免了不必要的DOM操作,提高了性能和代码可维护性,确保了无论点击方向如何,功能都能稳定运行。 动态菜单高亮…

    2026年5月10日
    200
  • html5怎么画实线_HTML5用CSS border-style:solid画元素实线边框【绘制】

    可通过CSS的border-style属性设为solid添加实线边框:一、内联样式用border:2px solid #000;二、内部样式表统一设置如div{border:1px solid #333};三、外部CSS文件定义.my-box{border:3px solid red}并引入;四、单…

    2026年5月10日
    200
  • JavaScript函数中插入加载动画(Spinner)的正确方法

    本文旨在解决在JavaScript函数中插入加载动画(Spinner)时遇到的异步问题。通过引入async/await和Promise.all,确保在数据处理完成前后正确显示和隐藏加载动画,提升用户体验。我们将提供两种实现方案,并详细解释其原理和优势。 在Web开发中,当执行耗时操作时,显示加载动画…

    2026年5月10日
    000
  • css如何禁止滚动条

    css禁止滚动条的方法:1、完全隐藏,代码为【】;2、在不需要时隐藏,代码为【】;3、样式表方法。 本教程操作环境:windows7系统、css3版,DELL G3电脑。 1、完全隐藏 在里加入scroll=”no”,可隐藏滚动条;   立即学习“前端免费学习笔记(深入)”;…

    2026年5月10日
    000
  • 动态更新圆形进度条:JavaScript成绩计算器集成指南

    本文档旨在指导开发者如何将JavaScript成绩计算系统与动态圆形进度条集成,实现可视化展示平均成绩。我们将详细讲解如何修改现有的JavaScript代码,使其在计算出平均分后,能够动态更新圆形进度条的进度,从而提供更直观的用户体验。本文档包含详细的代码示例和注意事项,帮助开发者轻松实现这一功能。…

    2026年5月10日
    000
  • React组件中动态属性值的管理与同步:利用状态实现受控组件

    本教程旨在解决react组件中动态属性值同步使用的问题。我们将探讨如何利用react的`usestate` hook来管理组件内部状态,从而实现一个属性的值动态地影响另一个属性,并构建出可预测、易于维护的受控组件。文章将通过具体代码示例,详细阐述从初始化状态到处理状态更新的完整过程,并强调受控组件在…

    2026年5月10日
    000
  • 如何讲html和css_讲解HTML与CSS结合使用基础【基础】

    需将HTML与CSS结合使用以实现网页结构与样式的分离:HTML定义标题、段落等语义结构,CSS控制颜色、字体等外观;可通过内联样式、内部样式表或外部CSS文件引入样式,并利用类选择器和ID选择器精准应用。 如果您希望网页不仅展示内容,还能具备基本的样式和结构布局,则需要将HTML与CSS结合使用。…

    2026年5月10日
    000
  • CSS伪元素与固定背景:移动友好的实现策略

    本文深入探讨了如何利用CSS的::before伪元素、position: fixed和z-index属性,创建一种在移动设备上表现更稳定的全屏固定背景效果,以替代传统background-attachment: fixed可能存在的兼容性问题。教程将详细解析这些核心CSS概念及其在构建响应式布局中的…

    2026年5月10日
    000
  • JavaScript计算器开发:解决数值显示与初始化问题

    本教程深入探讨了使用JavaScript构建计算器时常见的数值显示异常问题,特别是由于类属性未初始化导致的`Cannot read properties of undefined`错误。我们将详细分析问题根源,并通过在构造函数中调用初始化方法来解决该问题,同时优化显示逻辑,确保计算器功能稳定且界面显…

    2026年5月10日
    000
  • 使用 Ajax 和 FormData 实现文件上传及文本数据提交的完整教程

    本文旨在解决在使用 Ajax 和 FormData 进行文件上传时,遇到的 $_POST 和 $_FILES 为空的问题。通过详细的代码示例和解释,我们将展示如何正确地构建 FormData 对象,并通过 Ajax 将文件和文本数据发送到服务器端,同时避免常见的错误配置,确保数据能够成功地被 PHP…

    2026年5月10日
    000
  • JavaScript 高效判断页面所有复选框状态的技巧与实践

    本文旨在提供一套高效且专业的javascript方法,用于判断网页中所有复选框的选中状态。我们将探讨如何利用`array.some()`快速确定是否有未选中的复选框(进而判断是否全部选中),以及如何使用`array.filter()`统计选中和未选中的复选框数量。通过优化dom元素选择和数组操作,提…

    2026年5月10日
    000
  • HTML表单如何实现PWA支持?怎样添加离线功能?

    答案是利用Service Worker缓存资源并结合Background Sync API实现离线提交与自动同步。通过注册Service Worker缓存表单相关文件,拦截提交行为,将离线数据存入IndexedDB,并注册后台同步任务,待网络恢复后由Service Worker自动发送数据,确保提交…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信