一、基本思路

1、先看最终的效果图:

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

二、代码实现

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>css布局-瀑布流的实现</title>
<style type="text/css">
.box {
position: relative;
width: 500px;
min-height: 100px;
margin: 100px auto;
background: #eeeeee;
}
.item {
position: absolute;
width: 120px;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="box">
<div class="item" style="height: 40px;background: red;"></div>
<div class="item" style="height: 50px;background: blue;"></div>
<div class="item" style="height: 100px;background: green;"></div>
<div class="item" style="height: 60px;background: gray;"></div>
<div class="item" style="height: 50px;background: orange;"></div>
<div class="item" style="height: 20px;background: yellow;"></div>
<div class="item" style="height: 40px;background: red;"></div>
<div class="item" style="height: 50px;background: blue;"></div>
<div class="item" style="height: 100px;background: green;"></div>
<div class="item" style="height: 120px;background: gray;"></div>
<div class="item" style="height: 58px;background: orange;"></div>
<div class="item" style="height: 36px;background: yellow;"></div>
</div>
<script type="text/javascript">
const BOX_WIDTH = document.querySelector('.box').offsetWidth //瀑布流外层盒子的宽度
const ITEM_WIDTH = document.querySelector('.item').offsetWidth //瀑布流内层盒子的宽度
const COLUMN = Math.floor(BOX_WIDTH/ITEM_WIDTH) //根据宽度计算可渲染的列数
const MARGIN = (BOX_WIDTH - ITEM_WIDTH*COLUMN)/(COLUMN-1) // 根据宽度计算每一列的间距
const MARGINTOP = 10 //固定设置每一个小盒子上下间距是10
let height_arr = new Array(COLUMN).fill(0) //定义一个长度等同与列数的数组用来存储每一列的高度,初始值均为0
let item = document.querySelectorAll('.item')
//遍历每一个小盒子,确定小盒子的位置
for(let i = 0; i < item.length; i++) {
let index = height_arr.indexOf(Math.min.apply(null, height_arr))
item[i].style.left = (ITEM_WIDTH + MARGIN) * index + 'px'
item[i].style.top = height_arr[index] + MARGINTOP + 'px'
height_arr[index] += item[i].offsetHeight + MARGINTOP
}
//将数组中最大的值,即最高的那一列的高度赋给外层盒子
document.querySelector('.box').style.height = Math.max.apply(null, height_arr) + 'px'
</script>
</body>
</html>

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>css布局-瀑布流的实现</title>
<style type="text/css">
.box {
position: relative;
width: 500px;
min-height: 100px;
margin: 100px auto;
background: #eeeeee;
}
.item {
position: absolute;
width: 120px;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="box" style="">
<div class="item" style="height: 40px;background: red;"></div>
<div class="item" style="height: 50px;background: blue;"></div>
<div class="item" style="height: 100px;background: green;"></div>
<div class="item" style="height: 60px;background: gray;"></div>
<div class="item" style="height: 50px;background: orange;"></div>
<div class="item" style="height: 20px;background: yellow;"></div>
   <div class="item" style="height: 40px;background: red;"></div>
   <div class="item" style="height: 50px;background: blue;"></div>
   <div class="item" style="height: 100px;background: green;"></div>
   <div class="item" style="height: 120px;background: gray;"></div>
   <div class="item" style="height: 58px;background: orange;"></div>
   <div class="item" style="height: 36px;background: yellow;"></div>
</div>
<script type="text/javascript">
function WaterFall(params) {
this.box = (params && params.parent) || '.box'
this.item = (params && params.child) || '.item'
this.column = (params && params.column) || 0
this.row_margin = (params && params.row_margin) || 0
this.column_margin = (params && params.column_margin) || 10
this.height_arr = []
this._box_width = 0
this._item_width = 0
this._computed = function() {
this._box_width = document.querySelector(this.box).offsetWidth
this._item_width = document.querySelector(this.item).offsetWidth
this.column = Math.floor((this._box_width - this.row_margin)/this._item_width) //列数
this.row_margin = !this.row_margin ? (this._box_width - this._item_width * this.column)/(this.column-1) : this.row_margin
}
this.init = function() {
this._computed()
let item = document.querySelectorAll(this.item)
this.height_arr = new Array(this.column).fill(0)
for(let i = 0; i < item.length; i++) {
let index = this.height_arr.indexOf(Math.min.apply(null, this.height_arr))
item[i].style.left = (this._item_width + this.row_margin) * index + 'px'
item[i].style.top = this.height_arr[index] + this.column_margin + 'px'
this.height_arr[index] += item[i].offsetHeight + this.column_margin
}
document.querySelector('.box').style.height = Math.max.apply(null, this.height_arr) + 'px'
}
}
var test = new WaterFall()
test.init()
</script>
</body>
</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. delphi基础篇之数据类型之三:3.结构类型(Struct)

    3.结构类型(Struct) 结构类型在内存中存储一组相关的数据项,而不是像简单数据类型那样单一的数值.结构数据类型包括:集合类型.数组类型.记录类型.文件类型.类类型.类引用类型和接口类型等.

  2. C++——指针与数组

    1.数组名不是指针,神似指针(可以将数组名直接赋值给指针) (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组:(2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针 ...

  3. vue富文本vue-quill-editor

    这个富文本需要装一下插件 "quill": "^1.3.6" "quill-image-drop-module": "^1.0.3 ...

  4. yield迭代器的使用

    class Program { static void Main(string[] args) { List<Student> students = new List<Student ...

  5. HTML中<frameset>标签不显示的问题

    啥都不说,先上代码 <html> <head> <title>index</title> <meta content = 'text/html'; ...

  6. jenkins构建参数

    $BUILD_NUMBER 构建序号 $WORKSPACE 工作目录 #!/bin/sh - chmod u+x mvnw./mvnw package -Pprod -Dmaven.test.skip ...

  7. 8-vim-移动命令-03-段落切换和括号切换

    1.段落切换 vi使用空行来区分段落 在程序开发时,通常一段功能相关的代码会写在一起--之间没有空行 命令 功能 { 上一段 } 下一段 2.括号切换 在程序世界中,() [] {}使用频率很高,而且 ...

  8. 3-vim-打开和新建文件-02-删除交换文件

    vim的异常处理 如果vim异常退出,在磁盘上可能会保存有交换文件. 若使用vi编辑该文件时看到如下图信息,按下字母d就可以删除交换文件. 注意:输入命令操作的时候关闭输入法.

  9. linux每日命令(1):gzip命令

    gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用. gzip不仅可以用来压缩大的.较少使用的文件以节省磁盘空间,还可以和tar命令一起构成Linux操作系统中比较流 ...

  10. jq容易混淆点

    jQuery链式编程: 原:把当前元素颜色修改为红色,其余兄弟颜色不变 $(this).css("color",'red') ; $(this).siblings().css(&q ...