实现一个瀑布流布局
1、纯CSS实现
实现方式:借助column-count属性来创建 4 列的布局,并使用 column-gap 设置列间距。每个 .img-container 使用 break-inside: avoid 来防止图片被分割。
来看一下完整的代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<div id="container"><span>啊!瀑布!column-count的实现</span><div id="box-container" class="box-container"><!-- <div class="img-container"><img src="../../assets/images/test/test (1).jpg" alt=""></div> --></div>
</div>
</body>
<script>const boxContainer = document.getElementById('box-container');const imgCount = 32;for (let i = 1; i <= imgCount; i++) {const imgContainer = document.createElement('div');imgContainer.className = 'img-container';const img = document.createElement('img');img.src = `./test${i}.webp`;img.alt = `Image ${i}`;imgContainer.appendChild(img);boxContainer.appendChild(imgContainer);}</script>
<style>body {margin: 0;padding: 0;box-sizing: border-box;}#container {position: relative;}.box-container {padding: 5px;column-count: 5; /* 设置列数 */column-gap: 10px; /* 设置列间距 */}.img-container {width: 200px;padding: 5px;break-inside: avoid; /* 防止图片被分割 */margin-bottom: 10px;border-radius: 4px;}img {width: 100%;border-radius: 4px;border: 1px solid #666;}</style>
</html>
来看一下最终的效果吧:
2、CSS+JavaScript
特点:布局是从左到右,然后从上到下,一行一行地展示。
实现方法:每个 .img-container 元素使用 position: absolute 进行绝对定位。
JavaScript 代码计算每个元素的水平和垂直位置,并通过 transform: translate(x, y) 设置位置。
通过计算每列的高度,确保每个元素放置在高度最小的列中,从而实现瀑布流布局。
具体代码:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<div id="container"><span>啊!瀑布!CSS+JS的实现</span><div id="box-container" class="box-container"><!-- <div class="img-container"><img src="../../assets/images/test/test (1).jpg" alt=""></div> --></div>
</div>
</body>
<script>// 生成图片const boxContainer = document.getElementById('box-container');const imgCount = 11;for (let i = 1; i <= imgCount; i++) {const imgContainer = document.createElement('div');imgContainer.className = 'img-container';const img = document.createElement('img');img.src = `./test${i}.webp`;img.alt = `Image ${i}`;imgContainer.appendChild(img);boxContainer.appendChild(imgContainer);}// 瀑布流布局function masonryLayout(containerSelector) {const container = document.querySelector(containerSelector);const items = Array.from(container.children);const columnCount = Math.floor(container.offsetWidth / 216); // 计算列数const columnHeights = Array(columnCount).fill(0); // 初始化每列高度items.forEach((item) => {const minColumnIndex = columnHeights.indexOf(Math.min(...columnHeights)); // 找到高度最小的列const x = minColumnIndex * 216; // 水平位置const y = columnHeights[minColumnIndex]; // 垂直位置item.style.transform = `translate(${x}px, ${y}px)`; // 设置位置columnHeights[minColumnIndex] += item.offsetHeight + 16; // 更新列高度});// 更新容器高度container.style.height = Math.max(...columnHeights) + 'px';}// 调用函数window.addEventListener('load', () => masonryLayout('.box-container'));window.addEventListener('resize', () => masonryLayout('.box-container'));</script>
<style>body {margin: 0;padding: 0;box-sizing: border-box;}#container {position: relative;}.box-container {position: relative;width: 100%;}.img-container {background: #f2f2f2;border: 1px solid #ddd;break-inside: avoid; /* 避免内容被切断 */border-radius: 4px;position: absolute;width: 200px; /* 每列固定宽度 */margin: 8px;}img {width: 100%;display: block; /* 保证图片按比例缩放 */border-radius: 4px;border: 1px solid #666;}
</style>
</style>
</html>
实现效果: