• 多列布局以多列形式展示。
  • 不等高排列:每列的高度不固定,像瀑布一样错落有致。
  • 响应式:在不同屏幕尺寸下(桌面、平板、手机),列数会自动调整。

下面我将为你提供两种最主流的实现方式:

bootstrap模板 瀑布
(图片来源网络,侵删)
  1. 纯 CSS 方案 (推荐):使用 Bootstrap 5 内置的 masonry 插件,这是最简单、最现代、性能最好的方法。
  2. JavaScript 方案 (兼容旧版):使用经典的 JavaScript 库(如 Masonry 或 Isotope),这种方法更灵活,但需要引入额外的 JS 库。

使用 Bootstrap 5 内置的 masonry 插件 (推荐)

这是 Bootstrap 5 官方提供的解决方案,与框架无缝集成,使用起来非常简单。

步骤 1:引入 Bootstrap 资源

确保你的 HTML 文件中引入了 Bootstrap 的 CSS 和 JS 文件。注意:你需要引入包含 masonry 插件的完整 JS 文件。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">Bootstrap 5 瀑布流示例</title>
    <!-- 1. 引入 Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        /* 自定义样式,让瀑布流效果更明显 */
        .masonry-item {
            break-inside: avoid; /* 防止卡片内部被分页 */
            margin-bottom: 1rem; /* 卡片之间的间距 */
        }
        .masonry-item .card {
            height: 100%; /* 让卡片填满网格项 */
        }
        .card-img-top {
            object-fit: cover; /* 让图片覆盖整个区域,不变形 */
            height: 200px; /* 可以设置一个固定高度,也可以不设置 */
        }
    </style>
</head>
<body>
    <div class="container py-5">
        <h1 class="text-center mb-4">Bootstrap 5 瀑布流</h1>
        <!-- 2. 创建一个行容器,并添加 .g-* 类来设置列间距 -->
        <div class="row g-4">
            <!-- 3. 创建瀑布流项目,使用 .col-* 类设置响应式宽度 -->
            <!-- 项目 1 -->
            <div class="col-sm-6 col-md-4 col-lg-3 masonry-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/img1/400/600.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">卡片标题 1</h5>
                        <p class="card-text">这是一段较长的描述文本,用来展示卡片内容的高度是可变的,从而形成瀑布流效果。</p>
                    </div>
                </div>
            </div>
            <!-- 项目 2 -->
            <div class="col-sm-6 col-md-4 col-lg-3 masonry-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/img2/400/300.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">卡片标题 2</h5>
                        <p class="card-text">短文本。</p>
                    </div>
                </div>
            </div>
            <!-- 项目 3 -->
            <div class="col-sm-6 col-md-4 col-lg-3 masonry-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/img3/400/500.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">卡片标题 3</h5>
                        <p class="card-text">另一段中等长度的描述文本,看看它在布局中如何排列。</p>
                    </div>
                </div>
            </div>
            <!-- 项目 4 -->
            <div class="col-sm-6 col-md-4 col-lg-3 masonry-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/img4/400/700.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">卡片标题 4</h5>
                        <p class="card-text">这是一段非常非常非常长的描述文本,用来展示卡片内容的高度是可变的,从而形成瀑布流效果,它可能会占据两到三行的高度,让布局看起来更加错落有致。</p>
                    </div>
                </div>
            </div>
            <!-- 项目 5 -->
            <div class="col-sm-6 col-md-4 col-lg-3 masonry-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/img5/400/250.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">卡片标题 5</h5>
                        <p class="card-text">短文本。</p>
                    </div>
                </div>
            </div>
            <!-- 可以继续添加更多项目... -->
        </div>
    </div>
    <!-- 4. 引入 Bootstrap JS (包含 Popper 和所有插件) -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

核心要点解析:

  1. <div class="row g-4">: 这是 Bootstrap 的网格系统容器。g-4 (gap-4) 为列之间添加了间距,这是瀑布流布局的关键。
  2. <div class="col-sm-6 col-md-4 col-lg-3 masonry-item">: 这定义了每个卡片的响应式宽度。
    • col-sm-6: 在小屏幕上(手机),每行显示 2 个 (12 / 6 = 2)。
    • col-md-4: 在中等屏幕上(平板),每行显示 3 个 (12 / 4 = 3)。
    • col-lg-3: 在大屏幕上(桌面),每行显示 4 个 (12 / 3 = 4)。
    • masonry-item: 我们自定义的类,主要用于 break-inside: avoid 属性,防止浏览器在打印或分页时将卡片内容切断,同时作为逻辑上的瀑布流单元。
  3. break-inside: avoid: 这是 CSS 属性,告诉浏览器不要在这个元素的内部进行分页,在瀑布流布局中,它能确保一个完整的卡片不会被拆分到两列中去,是形成“瀑布”效果的关键。
  4. Bootstrap JS: 引入 bootstrap.bundle.min.js 是必须的,因为它包含了 masonry 插件所需的 JavaScript 代码,该插件会处理 CSS Grid 布局,实现真正的瀑布流排列。

使用 JavaScript 库 (Masonry.js) 兼容旧版

如果你使用的是 Bootstrap 4 或更早版本,或者需要更强大的功能(如过滤、排序),可以使用独立的 Masonry.js 库。

步骤 1:引入资源

除了 Bootstrap 的 CSS/JS,你还需要引入 Masonry.js 和它的 CSS(可选,但推荐)。

bootstrap模板 瀑布
(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">JavaScript 瀑布流示例</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Masonry CSS (可选,但推荐) -->
    <link rel="stylesheet" href="https://unpkg.com/masonry-layout@4/dist/masonry.min.css">
    <style>
        /* 网格项容器 */
        .grid-item {
            width: 100%; /* 由父容器 col-* 控制宽度 */
            margin-bottom: 1rem;
        }
        .grid-item .card {
            height: 100%;
        }
        .card-img-top {
            object-fit: cover;
        }
    </style>
</head>
<body>
    <div class="container py-5">
        <h1 class="text-center mb-4">JavaScript (Masonry.js) 瀑布流</h1>
        <!-- 2. 创建一个包裹容器,用于初始化 Masonry -->
        <div class="row" id="masonry-container">
            <!-- 3. 创建瀑布流项目,使用 Bootstrap 的列系统控制宽度 -->
            <!-- 项目 1 -->
            <div class="col-md-4 col-sm-6 grid-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/js1/400/600.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">JS 卡片标题 1</h5>
                        <p class="card-text">这是一段较长的描述文本,用来展示卡片内容的高度是可变的,从而形成瀑布流效果。</p>
                    </div>
                </div>
            </div>
            <!-- 项目 2 -->
            <div class="col-md-4 col-sm-6 grid-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/js2/400/300.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">JS 卡片标题 2</h5>
                        <p class="card-text">短文本。</p>
                    </div>
                </div>
            </div>
            <!-- 项目 3 -->
            <div class="col-md-4 col-sm-6 grid-item">
                <div class="card">
                    <img src="https://picsum.photos/seed/js3/400/500.jpg" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">JS 卡片标题 3</h5>
                        <p class="card-text">另一段中等长度的描述文本。</p>
                    </div>
                </div>
            </div>
            <!-- ... 更多项目 ... -->
        </div>
    </div>
    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
    <!-- Masonry JS -->
    <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
    <!-- 4. 初始化 Masonry 布局 -->
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            var grid = document.querySelector('#masonry-container');
            var msnry = new Masonry(grid, {
                // Masonry 的选项
                itemSelector: '.grid-item',
                columnWidth: '.grid-item', // 基于网格项的宽度来计算列宽
                gutter: 1rem // 列间距,这里用 rem 单位
            });
        });
    </script>
</body>
</html>

核心要点解析:

  1. <div id="masonry-container" class="row">: 这个 div 是 Masonry 布局的“网格容器”,它不直接使用 Bootstrap 的 g-* 类来控制间距,而是由 Masonry JS 来管理。
  2. <div class="col-md-4 col-sm-6 grid-item">: 每个卡片是“网格项”。
    • col-md-4 等 Bootstrap 类仍然负责响应式宽度控制。
    • grid-item 是我们自定义的类,用于 Masonry JS 识别 (itemSelector: '.grid-item')。
  3. 引入 Masonry.js: 在 Bootstrap 之后引入这个库。
  4. 初始化代码:
    • new Masonry(container, options): 创建一个新的 Masonry 实例。
    • itemSelector: '.grid-item': 告诉 Masonry 哪些元素是布局项目。
    • columnWidth: '.grid-item': 告诉 Masonry 如何确定列宽,因为我们用 Bootstrap 的列系统控制了每个项目的宽度,所以直接引用它即可。
    • gutter: 1rem: 设置项目之间的间距。

总结与选择

特性 方案一 (Bootstrap 5 masonry) 方案二 (Masonry.js)
实现方式 纯 CSS +少量 JS 纯 JavaScript
依赖 仅 Bootstrap 5 Bootstrap + Masonry.js
性能 极佳,浏览器原生渲染,性能最好 良好,但 JS 计算会有一定开销
易用性 极高,只需添加类名,无需 JS 初始化 一般,需要编写 JS 初始化代码
灵活性 较低,主要用于瀑布流 极高,支持过滤、排序、动画等高级功能
兼容性 仅 Bootstrap 5 兼容所有版本,甚至可以不依赖 Bootstrap

如何选择?

  • 新项目,使用 Bootstrap 5毫不犹豫选择方案一,它是官方解决方案,性能最好,代码最简洁。
  • 旧项目 (Bootstrap 4/3):如果只是需要瀑布流功能,可以考虑使用方案二,但如果项目复杂,有排序、筛选需求,方案二是更好的选择。
  • 不使用 Bootstrap:你可以直接使用 Masonry.js 或 Isotope.js,并配合自定义的 CSS Grid 或 Flexbox 布局来实现。
bootstrap模板 瀑布
(图片来源网络,侵删)