瀑布流布局
砌体布局 columns 属性
代码实现
html
<style>
.container {
columns: 300px auto;
column-gap: 15px;
padding: 15px;
}
.item {
break-inside: avoid;
margin-bottom: 15px;
}
.item img {
width: 100%;
border-radius: 8px;
display: block;
}
</style>
<div class="container">
<div class="item"><img src="https://picsum.photos/320/320" /></div>
<div class="item"><img src="https://picsum.photos/360/300" /></div>
<div class="item"><img src="https://picsum.photos/210/200" /></div>
<div class="item"><img src="https://picsum.photos/330/350" /></div>
<div class="item"><img src="https://picsum.photos/340/350" /></div>
<div class="item"><img src="https://picsum.photos/210/280" /></div>
<div class="item"><img src="https://picsum.photos/210/320" /></div>
<div class="item"><img src="https://picsum.photos/180/320" /></div>
<div class="item"><img src="https://picsum.photos/280/360" /></div>
<div class="item"><img src="https://picsum.photos/250/280" /></div>
<div class="item"><img src="https://picsum.photos/290/360" /></div>
<div class="item"><img src="https://picsum.photos/300/220" /></div>
<div class="item"><img src="https://picsum.photos/390/340" /></div>
<div class="item"><img src="https://picsum.photos/200/390" /></div>
<div class="item"><img src="https://picsum.photos/390/440" /></div>
<div class="item"><img src="https://picsum.photos/430/310" /></div>
<div class="item"><img src="https://picsum.photos/190/370" /></div>
<div class="item"><img src="https://picsum.photos/290/330" /></div>
<div class="item"><img src="https://picsum.photos/250/410" /></div>
<div class="item"><img src="https://picsum.photos/230/380" /></div>
<div class="item"><img src="https://picsum.photos/260/370" /></div>
<div class="item"><img src="https://picsum.photos/210/430" /></div>
<div class="item"><img src="https://picsum.photos/290/310" /></div>
<div class="item"><img src="https://picsum.photos/430/290" /></div>
</div>JavaScript 动态计算图片位置
代码实现
html
<style>
#container {
position: relative;
}
img {
position: absolute;
}
</style>
<div id="container"></div>
<script>
const divContainer = document.getElementById('container')
const imgWidth = 220 //每张图片的固定宽度
//1. 加入图片元素
function createImgs() {
for (let i = 0; i <= 40; i++) {
const height = Math.ceil(Math.random() * 100 + 200)
const src = 'https://picsum.photos/220/' + height //生成图片的src路径
const img = document.createElement('img')
img.onload = setPoisions
img.src = src //设置src路径
divContainer.appendChild(img) //添加到容器中
}
}
createImgs()
// 2. 设置每张图片的位置
function setPoisions() {
/**
* 计算一共有多少列,以及每一列之间的间隙
*/
function cal() {
const containerWidth = divContainer.clientWidth //容器的宽度
//计算列的数量
const columns = Math.floor(containerWidth / imgWidth)
//计算间隙
const spaceNumber = columns + 1 //间隙数量
const leftSpace = containerWidth - columns * imgWidth //计算剩余的空间
const space = leftSpace / spaceNumber //每个间隙的空间
return {
space: space,
columns: columns
}
}
const info = cal() //得到列数,和 间隙的空间
const nextTops = new Array(info.columns) //该数组的长度为列数,每一项表示该列的下一个图片的纵坐标
nextTops.fill(0) //将数组的每一项填充为0
for (let i = 0; i < divContainer.children.length; i++) {
const img = divContainer.children[i]
//找到nextTops中的最小值作为当前图片的纵坐标
const minTop = Math.min.apply(null, nextTops)
img.style.top = minTop + 'px'
//重新设置数组这一项的下一个top值
const index = nextTops.indexOf(minTop) //得到使用的是第几列的top值
nextTops[index] += img.height + info.space
//横坐标
const left = (index + 1) * info.space + index * imgWidth
img.style.left = left + 'px'
}
const max = Math.max.apply(null, nextTops) //求最大值
divContainer.style.height = max + 'px' //3. 设置容器的高度
}
let timerId = null //一个计时器的id
window.onresize = function () {
//窗口尺寸变动后,重新排列
if (timerId) {
clearTimeout(timerId)
}
timerId = setTimeout(setPoisions, 300)
}
</script>