本章概述

Bootstrap 的网格系统是其最核心和强大的特性之一。本章将深入介绍网格系统的工作原理、响应式断点、布局技巧以及实际应用场景。通过本章学习,你将能够熟练使用网格系统创建各种复杂的响应式布局。

网格系统基础

1. 网格系统概念

Bootstrap 的网格系统基于 Flexbox 构建,采用 12 列布局,支持响应式设计。它由三个主要组件组成:

  • 容器 (Container):包装内容的最外层元素
  • 行 (Row):列的水平组合
  • 列 (Column):内容的容器
<!-- 基本网格结构 -->
<div class="container">
    <div class="row">
        <div class="col">
            列内容
        </div>
    </div>
</div>

2. 容器类型

固定宽度容器

<!-- .container - 在每个断点处有最大宽度 -->
<div class="container">
    <!-- 内容在不同屏幕尺寸下有固定的最大宽度 -->
    <div class="row">
        <div class="col">
            固定宽度容器内容
        </div>
    </div>
</div>

容器最大宽度:

// Bootstrap 5 容器断点
$container-max-widths: (
  sm: 540px,   // ≥576px
  md: 720px,   // ≥768px
  lg: 960px,   // ≥992px
  xl: 1140px,  // ≥1200px
  xxl: 1320px  // ≥1400px
);

流体容器

<!-- .container-fluid - 始终占据100%宽度 -->
<div class="container-fluid">
    <div class="row">
        <div class="col">
            流体容器内容
        </div>
    </div>
</div>

响应式容器

<!-- 响应式容器 - 在指定断点之前为100%宽度 -->
<div class="container-sm">在 sm 断点及以上为固定宽度</div>
<div class="container-md">在 md 断点及以上为固定宽度</div>
<div class="container-lg">在 lg 断点及以上为固定宽度</div>
<div class="container-xl">在 xl 断点及以上为固定宽度</div>
<div class="container-xxl">在 xxl 断点及以上为固定宽度</div>

3. 行和列基础

自动布局列

<!-- 等宽列 -->
<div class="container">
    <div class="row">
        <div class="col">
            1 of 2
        </div>
        <div class="col">
            2 of 2
        </div>
    </div>
    <div class="row">
        <div class="col">
            1 of 3
        </div>
        <div class="col">
            2 of 3
        </div>
        <div class="col">
            3 of 3
        </div>
    </div>
</div>

指定列宽

<!-- 基于内容的列宽 -->
<div class="container">
    <div class="row">
        <div class="col">
            1 of 3
        </div>
        <div class="col-6">
            2 of 3 (wider)
        </div>
        <div class="col">
            3 of 3
        </div>
    </div>
</div>

<!-- 固定列宽 -->
<div class="container">
    <div class="row">
        <div class="col-4">
            .col-4
        </div>
        <div class="col-4">
            .col-4
        </div>
        <div class="col-4">
            .col-4
        </div>
    </div>
</div>

响应式断点系统

1. 断点定义

Bootstrap 5 定义了六个响应式断点:

$grid-breakpoints: (
  xs: 0,        // 超小屏幕 (手机竖屏)
  sm: 576px,    // 小屏幕 (手机横屏)
  md: 768px,    // 中等屏幕 (平板竖屏)
  lg: 992px,    // 大屏幕 (平板横屏/小桌面)
  xl: 1200px,   // 超大屏幕 (桌面)
  xxl: 1400px   // 超超大屏幕 (大桌面)
);

2. 响应式列类

基本响应式列

<!-- 响应式列示例 -->
<div class="container">
    <div class="row">
        <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
            <!-- 
            xs: 12列 (100%宽度)
            sm: 6列 (50%宽度)
            md: 4列 (33.33%宽度)
            lg: 3列 (25%宽度)
            xl: 2列 (16.67%宽度)
            -->
            响应式列
        </div>
    </div>
</div>

混合使用断点

<!-- 复杂响应式布局 -->
<div class="container">
    <div class="row">
        <!-- 主内容区 -->
        <div class="col-12 col-lg-8">
            <h2>主要内容</h2>
            <p>在大屏幕上占8列,小屏幕上占满宽度</p>
        </div>
        
        <!-- 侧边栏 -->
        <div class="col-12 col-lg-4">
            <h3>侧边栏</h3>
            <p>在大屏幕上占4列,小屏幕上占满宽度</p>
        </div>
    </div>
    
    <!-- 卡片网格 -->
    <div class="row">
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">卡片 1</h5>
                    <p class="card-text">卡片内容</p>
                </div>
            </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">卡片 2</h5>
                    <p class="card-text">卡片内容</p>
                </div>
            </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">卡片 3</h5>
                    <p class="card-text">卡片内容</p>
                </div>
            </div>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">卡片 4</h5>
                    <p class="card-text">卡片内容</p>
                </div>
            </div>
        </div>
    </div>
</div>

3. 列排序和偏移

列偏移

<!-- 使用 offset 类创建列偏移 -->
<div class="container">
    <div class="row">
        <div class="col-md-4">.col-md-4</div>
        <div class="col-md-4 offset-md-4">.col-md-4 .offset-md-4</div>
    </div>
    <div class="row">
        <div class="col-md-3 offset-md-3">.col-md-3 .offset-md-3</div>
        <div class="col-md-3 offset-md-3">.col-md-3 .offset-md-3</div>
    </div>
    <div class="row">
        <div class="col-md-6 offset-md-3">.col-md-6 .offset-md-3</div>
    </div>
</div>

响应式偏移

<!-- 响应式偏移 -->
<div class="container">
    <div class="row">
        <div class="col-sm-5 col-md-6">.col-sm-5 .col-md-6</div>
        <div class="col-sm-5 offset-sm-2 col-md-6 offset-md-0">
            .col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0
        </div>
    </div>
</div>

列排序

<!-- 使用 order 类改变列顺序 -->
<div class="container">
    <div class="row">
        <div class="col order-last">
            第一列,但显示在最后
        </div>
        <div class="col order-first">
            第二列,但显示在最前
        </div>
        <div class="col">
            第三列,正常顺序
        </div>
    </div>
</div>

<!-- 数字排序 -->
<div class="container">
    <div class="row">
        <div class="col order-3">
            第一列 (order-3)
        </div>
        <div class="col order-1">
            第二列 (order-1)
        </div>
        <div class="col order-2">
            第三列 (order-2)
        </div>
    </div>
</div>

<!-- 响应式排序 -->
<div class="container">
    <div class="row">
        <div class="col-12 col-md-6 order-md-2">
            在移动设备上第一个,桌面上第二个
        </div>
        <div class="col-12 col-md-6 order-md-1">
            在移动设备上第二个,桌面上第一个
        </div>
    </div>
</div>

高级网格技巧

1. 嵌套网格

<!-- 嵌套网格系统 -->
<div class="container">
    <div class="row">
        <div class="col-sm-3">
            Level 1: .col-sm-3
        </div>
        <div class="col-sm-9">
            <div class="row">
                <div class="col-8 col-sm-6">
                    Level 2: .col-8 .col-sm-6
                </div>
                <div class="col-4 col-sm-6">
                    Level 2: .col-4 .col-sm-6
                </div>
            </div>
        </div>
    </div>
</div>

2. 自动边距对齐

<!-- 使用 margin 工具类对齐列 -->
<div class="container">
    <div class="row">
        <div class="col-md-4">.col-md-4</div>
        <div class="col-md-4 ms-auto">.col-md-4 .ms-auto</div>
    </div>
    <div class="row">
        <div class="col-md-3 ms-md-auto">.col-md-3 .ms-md-auto</div>
        <div class="col-md-3 ms-md-auto">.col-md-3 .ms-md-auto</div>
    </div>
    <div class="row">
        <div class="col-auto me-auto">.col-auto .me-auto</div>
        <div class="col-auto">.col-auto</div>
    </div>
</div>

3. 可变宽度内容

<!-- 基于内容宽度的列 -->
<div class="container">
    <div class="row justify-content-md-center">
        <div class="col col-lg-2">
            1 of 3
        </div>
        <div class="col-md-auto">
            Variable width content
        </div>
        <div class="col col-lg-2">
            3 of 3
        </div>
    </div>
    <div class="row">
        <div class="col">
            1 of 3
        </div>
        <div class="col-md-auto">
            Variable width content
        </div>
        <div class="col col-lg-2">
            3 of 3
        </div>
    </div>
</div>

对齐和分布

1. 垂直对齐

<!-- 行级垂直对齐 -->
<div class="container">
    <!-- 顶部对齐 -->
    <div class="row align-items-start" style="height: 200px;">
        <div class="col">
            One of three columns
        </div>
        <div class="col">
            One of three columns
        </div>
        <div class="col">
            One of three columns
        </div>
    </div>
    
    <!-- 居中对齐 -->
    <div class="row align-items-center" style="height: 200px;">
        <div class="col">
            One of three columns
        </div>
        <div class="col">
            One of three columns
        </div>
        <div class="col">
            One of three columns
        </div>
    </div>
    
    <!-- 底部对齐 -->
    <div class="row align-items-end" style="height: 200px;">
        <div class="col">
            One of three columns
        </div>
        <div class="col">
            One of three columns
        </div>
        <div class="col">
            One of three columns
        </div>
    </div>
</div>

<!-- 列级垂直对齐 -->
<div class="container">
    <div class="row" style="height: 200px;">
        <div class="col align-self-start">
            One of three columns
        </div>
        <div class="col align-self-center">
            One of three columns
        </div>
        <div class="col align-self-end">
            One of three columns
        </div>
    </div>
</div>

2. 水平对齐

<!-- 水平对齐 -->
<div class="container">
    <!-- 左对齐 -->
    <div class="row justify-content-start">
        <div class="col-4">
            One of two columns
        </div>
        <div class="col-4">
            One of two columns
        </div>
    </div>
    
    <!-- 居中对齐 -->
    <div class="row justify-content-center">
        <div class="col-4">
            One of two columns
        </div>
        <div class="col-4">
            One of two columns
        </div>
    </div>
    
    <!-- 右对齐 -->
    <div class="row justify-content-end">
        <div class="col-4">
            One of two columns
        </div>
        <div class="col-4">
            One of two columns
        </div>
    </div>
    
    <!-- 两端对齐 -->
    <div class="row justify-content-between">
        <div class="col-4">
            One of two columns
        </div>
        <div class="col-4">
            One of two columns
        </div>
    </div>
    
    <!-- 均匀分布 -->
    <div class="row justify-content-around">
        <div class="col-4">
            One of two columns
        </div>
        <div class="col-4">
            One of two columns
        </div>
    </div>
    
    <!-- 等间距分布 -->
    <div class="row justify-content-evenly">
        <div class="col-4">
            One of two columns
        </div>
        <div class="col-4">
            One of two columns
        </div>
    </div>
</div>

间距和边距

1. 行间距

<!-- 移除行间距 -->
<div class="container">
    <div class="row g-0">
        <div class="col-sm-6 col-md-8">.col-sm-6 .col-md-8</div>
        <div class="col-6 col-md-4">.col-6 .col-md-4</div>
    </div>
</div>

<!-- 自定义行间距 -->
<div class="container">
    <div class="row g-2">
        <div class="col-6">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
        <div class="col-6">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
    </div>
</div>

<!-- 响应式间距 -->
<div class="container">
    <div class="row g-2 g-md-3 g-lg-4">
        <div class="col">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
        <div class="col">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
    </div>
</div>

2. 水平和垂直间距

<!-- 只设置水平间距 -->
<div class="container">
    <div class="row gx-5">
        <div class="col">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
        <div class="col">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
    </div>
</div>

<!-- 只设置垂直间距 -->
<div class="container">
    <div class="row gy-5">
        <div class="col-6">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
        <div class="col-6">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
        <div class="col-6">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
        <div class="col-6">
            <div class="p-3 border bg-light">Custom column padding</div>
        </div>
    </div>
</div>

实际应用案例

1. 博客布局

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客布局示例</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <!-- 导航栏 -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="#">我的博客</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item">
                        <a class="nav-link active" href="#">首页</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">分类</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">关于</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    
    <!-- 主要内容 -->
    <div class="container my-5">
        <div class="row">
            <!-- 文章列表 -->
            <div class="col-12 col-lg-8">
                <div class="row g-4">
                    <!-- 文章卡片 -->
                    <div class="col-12">
                        <article class="card">
                            <div class="row g-0">
                                <div class="col-md-4">
                                    <img src="https://via.placeholder.com/300x200" class="img-fluid rounded-start h-100 object-fit-cover" alt="文章图片">
                                </div>
                                <div class="col-md-8">
                                    <div class="card-body">
                                        <h5 class="card-title">文章标题</h5>
                                        <p class="card-text">这是文章的摘要内容,简要介绍文章的主要内容...</p>
                                        <p class="card-text">
                                            <small class="text-muted">发布于 2023年12月1日</small>
                                        </p>
                                        <a href="#" class="btn btn-primary">阅读更多</a>
                                    </div>
                                </div>
                            </div>
                        </article>
                    </div>
                    
                    <!-- 更多文章... -->
                    <div class="col-12">
                        <article class="card">
                            <div class="card-body">
                                <h5 class="card-title">另一篇文章</h5>
                                <p class="card-text">文章摘要内容...</p>
                                <p class="card-text">
                                    <small class="text-muted">发布于 2023年11月28日</small>
                                </p>
                                <a href="#" class="btn btn-primary">阅读更多</a>
                            </div>
                        </article>
                    </div>
                </div>
                
                <!-- 分页 -->
                <nav aria-label="文章分页" class="mt-4">
                    <ul class="pagination justify-content-center">
                        <li class="page-item disabled">
                            <span class="page-link">上一页</span>
                        </li>
                        <li class="page-item active">
                            <span class="page-link">1</span>
                        </li>
                        <li class="page-item">
                            <a class="page-link" href="#">2</a>
                        </li>
                        <li class="page-item">
                            <a class="page-link" href="#">3</a>
                        </li>
                        <li class="page-item">
                            <a class="page-link" href="#">下一页</a>
                        </li>
                    </ul>
                </nav>
            </div>
            
            <!-- 侧边栏 -->
            <div class="col-12 col-lg-4">
                <div class="row g-4">
                    <!-- 搜索框 -->
                    <div class="col-12">
                        <div class="card">
                            <div class="card-header">
                                <h6 class="mb-0">搜索</h6>
                            </div>
                            <div class="card-body">
                                <div class="input-group">
                                    <input type="text" class="form-control" placeholder="搜索文章...">
                                    <button class="btn btn-outline-secondary" type="button">搜索</button>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 分类 -->
                    <div class="col-12">
                        <div class="card">
                            <div class="card-header">
                                <h6 class="mb-0">分类</h6>
                            </div>
                            <div class="card-body">
                                <ul class="list-unstyled">
                                    <li><a href="#" class="text-decoration-none">技术 (12)</a></li>
                                    <li><a href="#" class="text-decoration-none">生活 (8)</a></li>
                                    <li><a href="#" class="text-decoration-none">旅行 (5)</a></li>
                                    <li><a href="#" class="text-decoration-none">摄影 (3)</a></li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 最新文章 -->
                    <div class="col-12">
                        <div class="card">
                            <div class="card-header">
                                <h6 class="mb-0">最新文章</h6>
                            </div>
                            <div class="card-body">
                                <div class="d-flex mb-3">
                                    <img src="https://via.placeholder.com/60x60" class="rounded me-3" alt="文章缩略图">
                                    <div>
                                        <h6 class="mb-1"><a href="#" class="text-decoration-none">文章标题</a></h6>
                                        <small class="text-muted">2023-12-01</small>
                                    </div>
                                </div>
                                <div class="d-flex mb-3">
                                    <img src="https://via.placeholder.com/60x60" class="rounded me-3" alt="文章缩略图">
                                    <div>
                                        <h6 class="mb-1"><a href="#" class="text-decoration-none">另一篇文章</a></h6>
                                        <small class="text-muted">2023-11-28</small>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 页脚 -->
    <footer class="bg-dark text-white text-center py-4">
        <div class="container">
            <p>&copy; 2023 我的博客. 保留所有权利.</p>
        </div>
    </footer>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

2. 电商产品网格

<!-- 产品网格布局 -->
<div class="container my-5">
    <!-- 页面标题 -->
    <div class="row mb-4">
        <div class="col-12">
            <h1 class="text-center">热门产品</h1>
            <p class="text-center text-muted">发现我们最受欢迎的产品</p>
        </div>
    </div>
    
    <!-- 筛选和排序 -->
    <div class="row mb-4">
        <div class="col-12 col-md-6">
            <div class="d-flex align-items-center">
                <label for="category" class="form-label me-2 mb-0">分类:</label>
                <select class="form-select" id="category" style="width: auto;">
                    <option>全部</option>
                    <option>电子产品</option>
                    <option>服装</option>
                    <option>家居</option>
                </select>
            </div>
        </div>
        <div class="col-12 col-md-6">
            <div class="d-flex align-items-center justify-content-md-end">
                <label for="sort" class="form-label me-2 mb-0">排序:</label>
                <select class="form-select" id="sort" style="width: auto;">
                    <option>默认</option>
                    <option>价格从低到高</option>
                    <option>价格从高到低</option>
                    <option>最新</option>
                </select>
            </div>
        </div>
    </div>
    
    <!-- 产品网格 -->
    <div class="row g-4">
        <!-- 产品卡片 -->
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥299</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 重复产品卡片... -->
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 2</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥199</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 更多产品... -->
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 3</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥399</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 4</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥599</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 继续添加更多产品... -->
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 5</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥799</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 6</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥999</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 7</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥1299</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="col-6 col-sm-6 col-md-4 col-lg-3">
            <div class="card h-100">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">产品名称 8</h5>
                    <p class="card-text flex-grow-1">产品描述信息...</p>
                    <div class="mt-auto">
                        <div class="d-flex justify-content-between align-items-center">
                            <span class="h5 text-primary mb-0">¥1599</span>
                            <button class="btn btn-primary btn-sm">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 加载更多按钮 -->
    <div class="row mt-5">
        <div class="col-12 text-center">
            <button class="btn btn-outline-primary btn-lg">加载更多产品</button>
        </div>
    </div>
</div>

3. 仪表板布局

<!-- 管理仪表板布局 -->
<div class="container-fluid">
    <div class="row">
        <!-- 侧边栏 -->
        <nav class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
            <div class="position-sticky pt-3">
                <ul class="nav flex-column">
                    <li class="nav-item">
                        <a class="nav-link active" href="#">
                            <i class="bi bi-house"></i>
                            仪表板
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">
                            <i class="bi bi-file-earmark"></i>
                            订单
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">
                            <i class="bi bi-cart"></i>
                            产品
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">
                            <i class="bi bi-people"></i>
                            客户
                        </a>
                    </li>
                </ul>
            </div>
        </nav>
        
        <!-- 主内容区 -->
        <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
            <!-- 页面标题 -->
            <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                <h1 class="h2">仪表板</h1>
                <div class="btn-toolbar mb-2 mb-md-0">
                    <div class="btn-group me-2">
                        <button type="button" class="btn btn-sm btn-outline-secondary">分享</button>
                        <button type="button" class="btn btn-sm btn-outline-secondary">导出</button>
                    </div>
                    <button type="button" class="btn btn-sm btn-primary">
                        <i class="bi bi-calendar"></i>
                        本周
                    </button>
                </div>
            </div>
            
            <!-- 统计卡片 -->
            <div class="row g-3 mb-4">
                <div class="col-12 col-sm-6 col-lg-3">
                    <div class="card text-white bg-primary">
                        <div class="card-body">
                            <div class="d-flex justify-content-between">
                                <div>
                                    <h4 class="card-title">1,234</h4>
                                    <p class="card-text">总订单</p>
                                </div>
                                <div class="align-self-center">
                                    <i class="bi bi-cart-fill fs-1"></i>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-12 col-sm-6 col-lg-3">
                    <div class="card text-white bg-success">
                        <div class="card-body">
                            <div class="d-flex justify-content-between">
                                <div>
                                    <h4 class="card-title">¥56,789</h4>
                                    <p class="card-text">总收入</p>
                                </div>
                                <div class="align-self-center">
                                    <i class="bi bi-currency-dollar fs-1"></i>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-12 col-sm-6 col-lg-3">
                    <div class="card text-white bg-warning">
                        <div class="card-body">
                            <div class="d-flex justify-content-between">
                                <div>
                                    <h4 class="card-title">567</h4>
                                    <p class="card-text">新客户</p>
                                </div>
                                <div class="align-self-center">
                                    <i class="bi bi-people-fill fs-1"></i>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-12 col-sm-6 col-lg-3">
                    <div class="card text-white bg-info">
                        <div class="card-body">
                            <div class="d-flex justify-content-between">
                                <div>
                                    <h4 class="card-title">89</h4>
                                    <p class="card-text">待处理</p>
                                </div>
                                <div class="align-self-center">
                                    <i class="bi bi-clock-fill fs-1"></i>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 图表和表格 -->
            <div class="row g-3">
                <!-- 图表区域 -->
                <div class="col-12 col-lg-8">
                    <div class="card">
                        <div class="card-header">
                            <h5 class="card-title mb-0">销售趋势</h5>
                        </div>
                        <div class="card-body">
                            <div class="chart-container" style="height: 300px; background-color: #f8f9fa; display: flex; align-items: center; justify-content: center;">
                                <p class="text-muted">图表区域 (集成 Chart.js 或其他图表库)</p>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 最新活动 -->
                <div class="col-12 col-lg-4">
                    <div class="card">
                        <div class="card-header">
                            <h5 class="card-title mb-0">最新活动</h5>
                        </div>
                        <div class="card-body">
                            <div class="d-flex mb-3">
                                <div class="flex-shrink-0">
                                    <div class="bg-primary rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
                                        <i class="bi bi-cart text-white"></i>
                                    </div>
                                </div>
                                <div class="flex-grow-1 ms-3">
                                    <h6 class="mb-1">新订单</h6>
                                    <p class="mb-0 text-muted small">订单 #1234 已创建</p>
                                    <small class="text-muted">2分钟前</small>
                                </div>
                            </div>
                            
                            <div class="d-flex mb-3">
                                <div class="flex-shrink-0">
                                    <div class="bg-success rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
                                        <i class="bi bi-person text-white"></i>
                                    </div>
                                </div>
                                <div class="flex-grow-1 ms-3">
                                    <h6 class="mb-1">新用户注册</h6>
                                    <p class="mb-0 text-muted small">张三 已注册</p>
                                    <small class="text-muted">5分钟前</small>
                                </div>
                            </div>
                            
                            <div class="d-flex">
                                <div class="flex-shrink-0">
                                    <div class="bg-warning rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
                                        <i class="bi bi-exclamation-triangle text-white"></i>
                                    </div>
                                </div>
                                <div class="flex-grow-1 ms-3">
                                    <h6 class="mb-1">库存警告</h6>
                                    <p class="mb-0 text-muted small">产品 A 库存不足</p>
                                    <small class="text-muted">10分钟前</small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 数据表格 -->
            <div class="row mt-4">
                <div class="col-12">
                    <div class="card">
                        <div class="card-header">
                            <h5 class="card-title mb-0">最新订单</h5>
                        </div>
                        <div class="card-body">
                            <div class="table-responsive">
                                <table class="table table-striped">
                                    <thead>
                                        <tr>
                                            <th>订单号</th>
                                            <th>客户</th>
                                            <th>产品</th>
                                            <th>金额</th>
                                            <th>状态</th>
                                            <th>操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td>#1234</td>
                                            <td>张三</td>
                                            <td>产品 A</td>
                                            <td>¥299</td>
                                            <td><span class="badge bg-success">已完成</span></td>
                                            <td>
                                                <button class="btn btn-sm btn-outline-primary">查看</button>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>#1235</td>
                                            <td>李四</td>
                                            <td>产品 B</td>
                                            <td>¥199</td>
                                            <td><span class="badge bg-warning">处理中</span></td>
                                            <td>
                                                <button class="btn btn-sm btn-outline-primary">查看</button>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>#1236</td>
                                            <td>王五</td>
                                            <td>产品 C</td>
                                            <td>¥399</td>
                                            <td><span class="badge bg-danger">已取消</span></td>
                                            <td>
                                                <button class="btn btn-sm btn-outline-primary">查看</button>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </div>
</div>

性能优化技巧

1. 减少不必要的列

<!-- 避免不必要的嵌套 -->
<!-- 不好的做法 -->
<div class="container">
    <div class="row">
        <div class="col-12">
            <div class="row">
                <div class="col-12">
                    内容
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 好的做法 -->
<div class="container">
    <div class="row">
        <div class="col-12">
            内容
        </div>
    </div>
</div>

2. 使用合适的容器类型

<!-- 根据需求选择容器类型 -->
<!-- 固定宽度布局 -->
<div class="container">
    <!-- 适合内容型网站 -->
</div>

<!-- 全宽布局 -->
<div class="container-fluid">
    <!-- 适合应用型界面 -->
</div>

<!-- 响应式容器 -->
<div class="container-lg">
    <!-- 在大屏幕上固定宽度,小屏幕上全宽 -->
</div>

3. 优化图片响应式

<!-- 响应式图片 -->
<div class="col-12 col-md-6 col-lg-4">
    <img src="image.jpg" class="img-fluid" alt="响应式图片">
</div>

<!-- 使用 srcset 优化 -->
<div class="col-12 col-md-6 col-lg-4">
    <img src="image-800.jpg" 
         srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
         sizes="(max-width: 768px) 100vw, (max-width: 992px) 50vw, 33vw"
         class="img-fluid" 
         alt="优化的响应式图片">
</div>

调试技巧

1. 网格调试 CSS

/* 临时调试样式 */
.debug-grid .container,
.debug-grid .container-fluid {
    outline: 2px solid blue;
}

.debug-grid .row {
    outline: 2px solid green;
}

.debug-grid [class*="col-"] {
    outline: 2px solid orange;
    min-height: 50px;
}

.debug-grid [class*="col-"]::before {
    content: attr(class);
    display: block;
    padding: 4px;
    background: rgba(0,0,0,0.1);
    font-size: 12px;
}
<!-- 使用调试类 -->
<div class="container debug-grid">
    <div class="row">
        <div class="col-md-6">列 1</div>
        <div class="col-md-6">列 2</div>
    </div>
</div>

2. 响应式调试

// JavaScript 调试工具
function showBreakpoint() {
    const breakpoints = {
        xs: 0,
        sm: 576,
        md: 768,
        lg: 992,
        xl: 1200,
        xxl: 1400
    };
    
    const width = window.innerWidth;
    let currentBreakpoint = 'xs';
    
    for (const [bp, minWidth] of Object.entries(breakpoints)) {
        if (width >= minWidth) {
            currentBreakpoint = bp;
        }
    }
    
    console.log(`当前断点: ${currentBreakpoint} (${width}px)`);
    
    // 在页面上显示
    let indicator = document.getElementById('breakpoint-indicator');
    if (!indicator) {
        indicator = document.createElement('div');
        indicator.id = 'breakpoint-indicator';
        indicator.style.cssText = `
            position: fixed;
            top: 10px;
            right: 10px;
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 5px 10px;
            border-radius: 3px;
            font-size: 12px;
            z-index: 9999;
        `;
        document.body.appendChild(indicator);
    }
    
    indicator.textContent = `${currentBreakpoint}: ${width}px`;
}

// 监听窗口大小变化
window.addEventListener('resize', showBreakpoint);
showBreakpoint(); // 初始调用

练习题

基础练习

  1. 基础网格布局

    • 创建一个三列等宽布局
    • 在移动设备上显示为单列
    • 在平板上显示为两列
    • 在桌面上显示为三列
  2. 响应式卡片网格

    • 创建一个产品展示页面
    • 使用卡片组件展示产品
    • 实现响应式网格布局
    • 添加适当的间距
  3. 复杂布局练习

    • 创建一个博客布局
    • 包含头部、主内容区、侧边栏和页脚
    • 实现响应式设计
    • 在移动设备上侧边栏移到主内容下方

进阶练习

  1. 仪表板布局

    • 创建一个管理后台界面
    • 包含侧边栏导航和主内容区
    • 实现统计卡片网格
    • 添加数据表格和图表区域
  2. 电商首页布局

    • 创建一个电商网站首页
    • 包含轮播图、分类导航、产品网格
    • 实现复杂的响应式布局
    • 优化移动端体验
  3. 自定义网格系统

    • 基于 Bootstrap 创建自定义断点
    • 实现 16 列网格系统
    • 添加自定义间距选项
    • 创建特殊的布局组件

本章总结

通过本章学习,我们深入掌握了:

  1. 网格系统基础:容器、行、列的概念和使用方法

  2. 响应式断点:六个断点的定义和响应式列类的使用

  3. 高级网格技巧:嵌套网格、列排序、偏移和对齐

  4. 实际应用案例:博客、电商、仪表板等不同类型的布局实现

  5. 性能优化:减少不必要嵌套、选择合适容器、优化图片

  6. 调试技巧:网格调试 CSS 和响应式调试工具

Bootstrap 的网格系统是构建响应式布局的强大工具,掌握它将让你能够快速创建适应各种设备的现代化网站布局。在下一章中,我们将学习 Bootstrap 的排版系统和文本工具。