一、基本思路

1、先看最终的效果图:

2、实现原理:通过position:absolute(绝对定位)来定位每一个元素的位置,并且将当前列的高度记录下来方便下一个dom位置的计算

二、代码实现

1、版本一:根据思路实现基础版

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>css布局-瀑布流的实现</title>
  6. <style type="text/css">
  7. .box {
  8. position: relative;
  9. width: 500px;
  10. min-height: 100px;
  11. margin: 100px auto;
  12. background: #eeeeee;
  13. }
  14. .item {
  15. position: absolute;
  16. width: 120px;
  17. left: 0;
  18. top: 0;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <div class="box">
  24. <div class="item" style="height: 40px;background: red;"></div>
  25. <div class="item" style="height: 50px;background: blue;"></div>
  26. <div class="item" style="height: 100px;background: green;"></div>
  27. <div class="item" style="height: 60px;background: gray;"></div>
  28. <div class="item" style="height: 50px;background: orange;"></div>
  29. <div class="item" style="height: 20px;background: yellow;"></div>
  30. <div class="item" style="height: 40px;background: red;"></div>
  31. <div class="item" style="height: 50px;background: blue;"></div>
  32. <div class="item" style="height: 100px;background: green;"></div>
  33. <div class="item" style="height: 120px;background: gray;"></div>
  34. <div class="item" style="height: 58px;background: orange;"></div>
  35. <div class="item" style="height: 36px;background: yellow;"></div>
  36. </div>
  37. <script type="text/javascript">
  38. const BOX_WIDTH = document.querySelector('.box').offsetWidth //瀑布流外层盒子的宽度
  39. const ITEM_WIDTH = document.querySelector('.item').offsetWidth //瀑布流内层盒子的宽度
  40. const COLUMN = Math.floor(BOX_WIDTH/ITEM_WIDTH) //根据宽度计算可渲染的列数
  41. const MARGIN = (BOX_WIDTH - ITEM_WIDTH*COLUMN)/(COLUMN-1) // 根据宽度计算每一列的间距
  42. const MARGINTOP = 10 //固定设置每一个小盒子上下间距是10
  43. let height_arr = new Array(COLUMN).fill(0) //定义一个长度等同与列数的数组用来存储每一列的高度,初始值均为0
  44. let item = document.querySelectorAll('.item')
    //遍历每一个小盒子,确定小盒子的位置
  45. for(let i = 0; i < item.length; i++) {
  46. let index = height_arr.indexOf(Math.min.apply(null, height_arr))
  47. item[i].style.left = (ITEM_WIDTH + MARGIN) * index + 'px'
  48. item[i].style.top = height_arr[index] + MARGINTOP + 'px'
  49. height_arr[index] += item[i].offsetHeight + MARGINTOP
  50. }
    //将数组中最大的值,即最高的那一列的高度赋给外层盒子
  51. document.querySelector('.box').style.height = Math.max.apply(null, height_arr) + 'px'
  52. </script>
  53. </body>
  54. </html>

2、版本二:对版本一进行封装,方便重复使用

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>css布局-瀑布流的实现</title>
  6. <style type="text/css">
  7. .box {
  8. position: relative;
  9. width: 500px;
  10. min-height: 100px;
  11. margin: 100px auto;
  12. background: #eeeeee;
  13. }
  14. .item {
  15. position: absolute;
  16. width: 120px;
  17. left: 0;
  18. top: 0;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <div class="box" style="">
  24. <div class="item" style="height: 40px;background: red;"></div>
  25. <div class="item" style="height: 50px;background: blue;"></div>
  26. <div class="item" style="height: 100px;background: green;"></div>
  27. <div class="item" style="height: 60px;background: gray;"></div>
  28. <div class="item" style="height: 50px;background: orange;"></div>
  29. <div class="item" style="height: 20px;background: yellow;"></div>
  30.    <div class="item" style="height: 40px;background: red;"></div>
  31.    <div class="item" style="height: 50px;background: blue;"></div>
  32.    <div class="item" style="height: 100px;background: green;"></div>
  33.    <div class="item" style="height: 120px;background: gray;"></div>
  34.    <div class="item" style="height: 58px;background: orange;"></div>
  35.    <div class="item" style="height: 36px;background: yellow;"></div>
  36. </div>
  37. <script type="text/javascript">
  38. function WaterFall(params) {
  39. this.box = (params && params.parent) || '.box'
  40. this.item = (params && params.child) || '.item'
  41. this.column = (params && params.column) || 0
  42. this.row_margin = (params && params.row_margin) || 0
  43. this.column_margin = (params && params.column_margin) || 10
  44. this.height_arr = []
  45. this._box_width = 0
  46. this._item_width = 0
  47. this._computed = function() {
  48. this._box_width = document.querySelector(this.box).offsetWidth
  49. this._item_width = document.querySelector(this.item).offsetWidth
  50. this.column = Math.floor((this._box_width - this.row_margin)/this._item_width) //列数
  51. this.row_margin = !this.row_margin ? (this._box_width - this._item_width * this.column)/(this.column-1) : this.row_margin
  52. }
  53. this.init = function() {
  54. this._computed()
  55. let item = document.querySelectorAll(this.item)
  56. this.height_arr = new Array(this.column).fill(0)
  57. for(let i = 0; i < item.length; i++) {
  58. let index = this.height_arr.indexOf(Math.min.apply(null, this.height_arr))
  59. item[i].style.left = (this._item_width + this.row_margin) * index + 'px'
  60. item[i].style.top = this.height_arr[index] + this.column_margin + 'px'
  61. this.height_arr[index] += item[i].offsetHeight + this.column_margin
  62. }
  63. document.querySelector('.box').style.height = Math.max.apply(null, this.height_arr) + 'px'
  64. }
  65. }
  66. var test = new WaterFall()
  67. test.init()
  68. </script>
  69. </body>
  70. </html>

三、总结:瀑布流的实现并不复杂,只要清楚了原理剩下的就是耐心的计算间距以及小盒子的位置啦~

css布局-瀑布流的实现的更多相关文章

  1. 简单CSS定位瀑布流实现方法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. js-实现多列布局(瀑布流)

    本文是使用面向对象的思想实现多列布局(瀑布流).当然,使用面向过程也能实现,具体效果图和案例如下: 具体实现代码如下: <!DOCTYPE html> <html lang=&quo ...

  3. 详解纯css实现瀑布流(multi-column多列及flex布局)

    瀑布流的布局自我感觉还是很吸引人的,最近又看到实现瀑布流这个做法,在这里记录下,特别的,感觉flex布局实现瀑布流还是有点懵的样子,不过现在就可以明白它的原理了 1.multi-column多列布局实 ...

  4. 纯css实现瀑布流(multi-column多列及flex布局)

    瀑布流的布局自我感觉还是很吸引人的,最近又看到实现瀑布流这个做法,在这里记录下,特别的,感觉flex布局实现瀑布流还是有点懵的样子,不过现在就可以明白它的原理了 1.multi-column多列布局实 ...

  5. css3多列布局瀑布流加载样式

    看了一些网站的瀑布流加载,正好看到css3的多列属性,尝试着写了一个css做布局的瀑布流. 直接上代码: <!DOCTYPE html> <html lang="en&qu ...

  6. 详细分享UICollectionView的自定义布局(瀑布流, 线性, 圆形…)

    前言: 本篇文章不是分享collectionView的详细使用教程, 而是属于比较’高级’的collectionView使用技巧, 阅读之前, 我想你已经很熟悉collectionView的基本使用, ...

  7. Objectiv-c - UICollectionViewLayout自定义布局-瀑布流

    最近刚写的一个简单的瀑布流. 整体思路可能不是很完善. 不过也算是实现效果了. 高手勿喷 思路: 自定义UICollectionViewLayout实际上就是需要返回每个item的fram就可以了. ...

  8. 分别用js和css实现瀑布流

    下午查找了瀑布流的相关原理,找了一些css3实现的还有js实现的,最后总结了一些比较简单的,易懂的整理起来 1.css3实现 只要运用到    column-count分列 column-width固 ...

  9. 详细分享UICollectionView的自定义布局(瀑布流, 线性, 圆形...)

    前言: 本篇文章不是分享collectionView的详细使用教程, 而是属于比较'高级'的collectionView使用技巧, 阅读之前, 我想你已经很熟悉collectionView的基本使用, ...

随机推荐

  1. Openstack组件部署 — Netwotking service组件介绍与网络基本概念

    目录 目录 前文列表 Openstack Networking serivce 基本的Neutron概念 Neutron的抽象对象 网络networks 子网subnets 路由器routers 端口 ...

  2. gitlab开机启动|启动 停止 重启

    修改配置后的初始化 gitlab-ctl reconfigure 启动 sudo gitlab-ctl start 停止sudo gitlab-ctl stop 重启sudo gitlab-ctl r ...

  3. js 中typeof 检测数据类型的时候需要注意的小细节

    博客搬迁给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/10/26/typeof-%E6%A3%80%E6%B5%8B%E6%95%B0%E6%8D% ...

  4. Python的序列化和反序列化

    序列化是将dict---->str 反序列化是将str---->dict import jsonresult1 = json.dumps({'a': 1, 'b': 2}) #序列化res ...

  5. Vue番外篇-路由进阶(一)

    Vue的router默认是 export default new Router({ mode: 'history', routes: [ { path: '/', name: 'HelloWorld' ...

  6. (Struts2学习系列四)Struts2指定配置文件

    我们的每个action都在struts.xml里配置的话,就会出现很多的xml语句,单单一个struts.xml就会变得很大,所以我们会在struts.xml里使用include引入其他的.xml文件 ...

  7. Jmeter-Json提取器、用户定义变量配置

    一.Jmeter用户定义的变量,一般用于配置全局变量 1.选择用户定义的变量菜单 2.配置需要的用户定义变量 这里我添加常用的localhost和port 3.如何使用 需要使用${...}进行引用 ...

  8. 开放应用模型(OAM):全球首个云原生应用标准定义与架构模型

    Kubernetes 项目作为容器编排领域的事实标准, 成功推动了诸如阿里云 Kubernetes (ACK)等云原生服务的迅速增长.但同时我们也关注到,Kubernetes 的核心 API 资源比如 ...

  9. NX二次开发-将工程图视图+尺寸的最大边界导出图片

    /***************************************************************************** ** ** ExportPicture.c ...

  10. NX二次开发-UFUN打开二进制STL文件函数UF_STD_open_binary_stl_file

    NX9+VS2012 #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <u ...