本章概述
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>© 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(); // 初始调用
练习题
基础练习
基础网格布局
- 创建一个三列等宽布局
- 在移动设备上显示为单列
- 在平板上显示为两列
- 在桌面上显示为三列
响应式卡片网格
- 创建一个产品展示页面
- 使用卡片组件展示产品
- 实现响应式网格布局
- 添加适当的间距
复杂布局练习
- 创建一个博客布局
- 包含头部、主内容区、侧边栏和页脚
- 实现响应式设计
- 在移动设备上侧边栏移到主内容下方
进阶练习
仪表板布局
- 创建一个管理后台界面
- 包含侧边栏导航和主内容区
- 实现统计卡片网格
- 添加数据表格和图表区域
电商首页布局
- 创建一个电商网站首页
- 包含轮播图、分类导航、产品网格
- 实现复杂的响应式布局
- 优化移动端体验
自定义网格系统
- 基于 Bootstrap 创建自定义断点
- 实现 16 列网格系统
- 添加自定义间距选项
- 创建特殊的布局组件
本章总结
通过本章学习,我们深入掌握了:
网格系统基础:容器、行、列的概念和使用方法
响应式断点:六个断点的定义和响应式列类的使用
高级网格技巧:嵌套网格、列排序、偏移和对齐
实际应用案例:博客、电商、仪表板等不同类型的布局实现
性能优化:减少不必要嵌套、选择合适容器、优化图片
调试技巧:网格调试 CSS 和响应式调试工具
Bootstrap 的网格系统是构建响应式布局的强大工具,掌握它将让你能够快速创建适应各种设备的现代化网站布局。在下一章中,我们将学习 Bootstrap 的排版系统和文本工具。