Bootstrap 的栅格系统(Grid System)是其最核心的布局能力之一,也是前端开发者从“手写 CSS”走向“工程化页面搭建”的必经之路。它通过一套语义化的类名、12 列的宽度划分以及五个响应式断点,把原本需要大量浮动、定位、媒体查询才能实现的复杂布局,转化为几行类名的组合。本章将从设计思想出发,逐层拆解容器、行、列、响应式类、偏移、排序、嵌套、间距等关键概念,并通过完整的 Bootstrap 5.3.2 示例演示每一种用法,最后用一个“响应式商品列表页”把知识串联起来。
一、栅格系统的设计思想 1.1 概念说明 栅格系统是一种把页面水平空间按照固定份数进行切分,从而指导内容摆放的设计与开发规范。Bootstrap 选择将每一行划分为 12 等份,开发者通过声明某块内容占据几份,来决定它的相对宽度。这种思想来源于平面排版中的“网格系统”:把杂乱无章的元素约束在看不见的基准线上,页面自然会显得整齐、统一、易于阅读。
在 Bootstrap 里,这份约束由 CSS Flexbox 实现。.row 被设置为 display: flex; flex-wrap: wrap;,.col-* 则通过 flex: 0 0 auto; width: N/12*100% 计算百分比宽度。由于整份系统建立在百分比而非固定像素之上,因此同一套类名可以在手机、平板、笔记本、大屏显示器上自动伸缩。
1.2 使用场景
快速原型 :产品经理或设计师只需要画出 12 列网格,开发者即可用 col-md-* 还原。
响应式页面 :同一套 HTML 结构在不同断点下呈现不同布局,例如移动端单栏、桌面端三栏。
团队协作 :约定俗成的类名降低了沟通成本,新成员加入项目后能迅速理解页面结构。
可维护性 :当需要调整宽度时,只需修改类名中的数字,无需重写大量 CSS。
1.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <!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" > <style > .box { background : #e3f2fd ; border : 1px solid #90caf9 ; padding : 1rem ; text-align : center; } </style > </head > <body > <div class ="container mt-4" > <h2 class ="mb-3" > 12 列栅格</h2 > <div class ="row" > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > <div class ="col-1 box" > 1</div > </div > <div class ="row mt-2" > <div class ="col-4 box" > 4/12</div > <div class ="col-4 box" > 4/12</div > <div class ="col-4 box" > 4/12</div > </div > <div class ="row mt-2" > <div class ="col-8 box" > 8/12</div > <div class ="col-4 box" > 4/12</div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
1.4 效果解析 页面会首先展示一行 12 个等宽小格子,每个占 1/12;接着是一行三等分的格子,各占 4/12;最后是一行 8:4 比例的两列。无论视口如何变化,这些比例始终保持,因为这是基于百分比的流体布局。通过这种方式,开发者可以直观地感受到“12 列”是如何被组合成不同版式的。
二、容器与行的关系 2.1 概念说明 Bootstrap 栅格系统的层级结构可以概括为:容器(Container) → 行(Row) → 列(Column) → 内容(Content) 。容器是外层约束,行负责包裹列并产生负边距抵消列的 padding,列是实际的内容承载单元。
Bootstrap 5 提供三种容器:
.container:在每个断点处拥有最大宽度,例如 sm 为 540px、md 为 720px、lg 为 960px、xl 为 1140px、xxl 为 1320px,达到最大宽度后不再扩展。
.container-fluid:始终占据 100% 宽度,适合需要全屏布局的 banner、仪表盘等场景。
.container-{breakpoint}:从指定断点开始变成 max-width 容器,小于该断点时与 .container-fluid 一样 100% 宽度。
行 .row 是 Flex 容器,会自动把子元素排成一行并允许换行。每一行的横向内边距由列来承担,而行本身通过 margin-left/right: calc(var(--bs-gutter-x) * -.5) 抵消这部分内边距,使列的内容与容器边缘对齐。
2.2 使用场景
.container 适合博客文章、电商详情页、表单页等需要控制阅读宽度的页面。
.container-fluid 适合后台管理系统、地图应用、沉浸式落地页。
.container-lg 适合“在中等屏幕以下全宽,在大屏上居中”的创意作品集。
2.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <!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" > <style > .demo-box { background : #fff3e0 ; border : 1px solid #ffcc80 ; padding : 1rem ; } .fluid-box { background : #e8f5e9 ; border : 1px solid #a5d6a7 ; padding : 1rem ; } </style > </head > <body > <div class ="container mt-4" > <h4 > 普通容器</h4 > <div class ="row" > <div class ="col demo-box" > 居中有最大宽度</div > </div > </div > <div class ="container-fluid mt-4" > <h4 > 流体容器</h4 > <div class ="row" > <div class ="col fluid-box" > 占满整个视口宽度</div > </div > </div > <div class ="container-lg mt-4" > <h4 > 断点容器</h4 > <div class ="row" > <div class ="col demo-box" > 大屏以下全宽,大屏居中</div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
2.4 效果解析 第一个区块会在屏幕中央有一个最大宽度,两侧留出空白;第二个区块的绿色背景会延伸到浏览器左右边缘;第三个区块在手机上是全宽,当屏幕达到 lg 断点后会变成固定最大宽度并居中。通过对比,可以清晰理解三种容器的行为差异。
三、12 列栅格原理 3.1 概念说明 Bootstrap 把每一行平均分成 12 列,这个数字的选择并非随意:12 可以被 1、2、3、4、6 整除,便于生成 1/2、1/3、1/4、1/6 等常见比例。列宽类 col-{number} 中的数字即表示该列占据的份数,总和不能超过 12;超过时会换行,不足 12 时剩余空间会根据列的 flex 行为分配。
在 Bootstrap 5 中,所有列默认具备 position: relative; padding-left/right: calc(var(--bs-gutter-x) * .5),因此列与列之间会产生由 CSS 变量控制的间距(gutter)。同时 .row 的负外边距会把第一列和最后一列的内边距“拉回来”,保证内容边缘与容器边缘对齐。
3.2 使用场景
等宽布局 :三栏卡片、四栏图标展示。
比例布局 :左侧侧边栏 3/12,右侧主内容 9/12。
混合布局 :顶部 banner 占 12/12,下方内容区分成 8:4。
3.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 12 列栅格原理</title > <link href ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel ="stylesheet" > <style > .cell { background : #ede7f6 ; border : 1px solid #b39ddb ; padding : .75rem ; text-align : center; } </style > </head > <body > <div class ="container mt-4" > <h3 class ="mb-3" > 常见比例组合</h3 > <div class ="row" > <div class ="col-6 cell" > 6/12 = 50%</div > <div class ="col-6 cell" > 6/12 = 50%</div > </div > <div class ="row mt-2" > <div class ="col-4 cell" > 4/12 ≈ 33.3%</div > <div class ="col-4 cell" > 4/12 ≈ 33.3%</div > <div class ="col-4 cell" > 4/12 ≈ 33.3%</div > </div > <div class ="row mt-2" > <div class ="col-3 cell" > 3/12 = 25%</div > <div class ="col-3 cell" > 3/12 = 25%</div > <div class ="col-3 cell" > 3/12 = 25%</div > <div class ="col-3 cell" > 3/12 = 25%</div > </div > <div class ="row mt-2" > <div class ="col-9 cell" > 9/12 = 75%</div > <div class ="col-3 cell" > 3/12 = 25%</div > </div > <div class ="row mt-2" > <div class ="col-5 cell" > 5/12</div > <div class ="col-5 cell" > 5/12</div > <div class ="col-2 cell" > 2/12</div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
3.4 效果解析 示例展示了 12 列最常见的几种切分方式。前两行分别是 6:6 和 4:4:4,适合两栏、三栏等宽布局;第三行是四栏,常用于底部链接、功能图标;第四行 9:3 适合“主内容 + 侧边栏”;最后一行 5:5:2 则演示了非对称比例的写法。所有比例相加都等于 12,若超过则会自动换行。
四、列宽类详解 4.1 概念说明 Bootstrap 5 的列宽类分为以下几类:
.col:自动等宽,所有列平分剩余空间。
.col-auto:宽度由内容决定,不占用固定份数。
.col-{number}:在所有屏幕尺寸下都占据固定份数。
.col-{breakpoint}-{number}:在指定断点及以上占据固定份数,小于断点时自动变成 100% 宽度(垂直堆叠)。
.col-{breakpoint}:在指定断点及以上自动等宽。
.col-{breakpoint}-auto:在指定断点及以上由内容决定宽度。
不带断点的 col-* 属于“ xs 默认”规则,即从最小屏幕开始生效;带断点的类属于“移动优先”规则,即只在断点及以上生效。因此 col-12 col-md-6 表示:手机端全宽,平板及以上占一半。
4.2 使用场景
.col 用于数量不确定、需要自动平分的导航项。
.col-auto 用于按钮、标签等“包裹内容即可”的元素。
.col-6 用于移动端两栏小卡片。
.col-md-4 用于平板以上三栏、手机上一栏的产品列表。
4.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <!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" > <style > .item { background : #fce4ec ; border : 1px solid #f48fb1 ; padding : .75rem ; text-align : center; } </style > </head > <body > <div class ="container mt-4" > <h4 > 自动等宽 .col</h4 > <div class ="row" > <div class ="col item" > A</div > <div class ="col item" > B</div > <div class ="col item" > C</div > </div > <h4 class ="mt-4" > 固定与自动混合</h4 > <div class ="row" > <div class ="col-3 item" > 固定 3</div > <div class ="col item" > 自动填充</div > <div class ="col-auto item" > 按内容</div > </div > <h4 class ="mt-4" > 设置一个列宽,其余自动</h4 > <div class ="row" > <div class ="col item" > 左</div > <div class ="col-7 item" > 中间 7/12</div > <div class ="col item" > 右</div > </div > <h4 class ="mt-4" > 断点类</h4 > <div class ="row" > <div class ="col-12 col-md-8 item" > 手机全宽,md 以上 8/12</div > <div class ="col-6 col-md-4 item" > 手机 6/12,md 以上 4/12</div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
4.4 效果解析 第一组三个 .col 会平分整行;第二组中,第一列固定占 3/12,第三列按内容宽度,剩余空间全给第二列;第三组中间列固定 7/12,左右两列自适应剩余空间;第四组展示了移动优先:手机端第一列全宽、第二列半宽,到了 md 断点后变为 8:4。这样一套类名即可覆盖从小屏到大屏的多种版式。
五、响应式栅格类 5.1 概念说明 Bootstrap 5 定义了六个断点,构成移动优先的响应式体系:
断点
类前缀
尺寸范围
xs
col-*
< 576px
sm
col-sm-*
≥ 576px
md
col-md-*
≥ 768px
lg
col-lg-*
≥ 992px
xl
col-xl-*
≥ 1200px
xxl
col-xxl-*
≥ 1400px
“移动优先”意味着:如果只在某个断点设置了类,那么小于该断点的屏幕会回退到默认行为——列会垂直堆叠,每个占满 100% 宽度。如果还配合了更小的断点类,则遵循“就近原则”:浏览器会选择当前视口满足的最大断点对应的类。
5.2 使用场景
手机单栏、平板双栏、桌面四栏 :col-12 col-sm-6 col-lg-3。
导航栏 :手机端垂直堆叠,桌面端水平排列。
图文混排 :小屏上图下文,大屏上左图右文。
5.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <!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" > <style > .card { background : #e0f2f1 ; border : 1px solid #80cbc4 ; padding : 1rem ; text-align : center; } </style > </head > <body > <div class ="container mt-4" > <h3 class ="mb-3" > 响应式商品卡片</h3 > <div class ="row g-3" > <div class ="col-12 col-sm-6 col-lg-3" > <div class ="card" > 商品 1<br > <small > 手机全宽 / sm 半宽 / lg 1/4</small > </div > </div > <div class ="col-12 col-sm-6 col-lg-3" > <div class ="card" > 商品 2<br > <small > 手机全宽 / sm 半宽 / lg 1/4</small > </div > </div > <div class ="col-12 col-sm-6 col-lg-3" > <div class ="card" > 商品 3<br > <small > 手机全宽 / sm 半宽 / lg 1/4</small > </div > </div > <div class ="col-12 col-sm-6 col-lg-3" > <div class ="card" > 商品 4<br > <small > 手机全宽 / sm 半宽 / lg 1/4</small > </div > </div > </div > <h3 class ="mt-4 mb-3" > 断点越丰富,控制越精细</h3 > <div class ="row g-2" > <div class ="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2 card" > 自适应</div > <div class ="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2 card" > 自适应</div > <div class ="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2 card" > 自适应</div > <div class ="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2 card" > 自适应</div > <div class ="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2 card" > 自适应</div > <div class ="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2 card" > 自适应</div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
5.4 效果解析 第一组商品卡片在手机端每行一个,到了 sm 断点后每行两个,到了 lg 断点后每行四个。第二组则进一步细化:手机一列、sm 两列、md 三列、lg 四列、xl 六列。这种“阶梯式”的响应式控制,使页面在不同设备上都能保持良好的可读性和空间利用率。
六、列偏移 6.1 概念说明 列偏移用于让某一列向右移动指定的列数,从而在不改变 HTML 结构的情况下产生留白或居中对齐效果。Bootstrap 5 提供两种实现方式:
offset 类 :offset-{breakpoint}-{number},通过 margin-left: N/12*100% 实现精确偏移。
margin 自动类 :ms-auto(margin-start auto)、me-auto(margin-end auto),在 Flex 容器中将列推到一侧。
offset 适合“精确控制列位置”的场景,例如居中登录框;margin 自动类适合“一侧贴边、另一侧留白”的场景,例如右侧固定按钮。
6.2 使用场景
居中表单 :col-md-6 offset-md-3 让 6 列宽的表单在 12 列中居中。
非对称布局 :左侧内容 4 列,右侧内容 4 列,中间留 4 列空白。
右对齐操作栏 :使用 ms-auto 把按钮组推到行右侧。
6.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!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" > <style > .cell { background : #f3e5f5 ; border : 1px solid #ce93d8 ; padding : .75rem ; text-align : center; } </style > </head > <body > <div class ="container mt-4" > <h4 > 居中对齐</h4 > <div class ="row" > <div class ="col-md-6 offset-md-3 cell" > col-md-6 offset-md-3</div > </div > <h4 class ="mt-4" > 非对称偏移</h4 > <div class ="row" > <div class ="col-md-4 cell" > col-md-4</div > <div class ="col-md-4 offset-md-4 cell" > col-md-4 offset-md-4</div > </div > <h4 class ="mt-4" > 双列间隔</h4 > <div class ="row" > <div class ="col-md-4 offset-md-1 cell" > 左偏移 1</div > <div class ="col-md-4 offset-md-2 cell" > 右偏移 2</div > </div > <h4 class ="mt-4" > margin 自动类实现右对齐</h4 > <div class ="row" > <div class ="col-auto cell" > 左侧固定</div > <div class ="col-auto ms-auto cell" > 被推到右侧</div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
6.4 效果解析 第一行中,6 列宽的单元格向左偏移 3 列,正好在 12 列中居中;第二行左侧列从第 1 列开始,右侧列从第 9 列开始,中间空出 4 列;第三行演示了左右两列的不同偏移量;第四行通过 ms-auto 把第二列推到右侧,常用于工具栏、按钮组。offset 是精确像素级(百分比级)控制,而 margin 自动类是弹性对齐控制。
七、列排序 7.1 概念说明 列排序允许开发者改变列在视觉上的排列顺序,而无需调整 HTML 的 DOM 顺序。它基于 CSS Flexbox 的 order 属性实现,通过 order-{number} 或 order-{breakpoint}-{number} 类控制。默认所有列的 order 为 0,数字越小越靠前,越大越靠后。
Bootstrap 5 还提供了几个语义化排序类:
.order-first:order 为 -1,排到最前面。
.order-last:order 为 6(在 12 列概念里),排到最后面。
.order-0 到 .order-5:常用排序数字。
7.2 使用场景
响应式图文顺序 :桌面端图片在左、文字在右,移动端文字在上、图片在下。
优先展示核心内容 :把 SEO 重要的正文放在 DOM 前面,但通过排序在视觉上后置。
动态调整导航顺序 :不同断点下高亮不同入口。
7.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!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" > <style > .block { padding : 1rem ; text-align : center; color : #fff ; } .a { background : #ef5350 ; } .b { background : #42a5f5 ; } .c { background : #66bb6a ; } .d { background : #ffa726 ; } </style > </head > <body > <div class ="container mt-4" > <h4 > 基本排序</h4 > <div class ="row" > <div class ="col order-3 block a" > A(DOM 第一)</div > <div class ="col order-1 block b" > B</div > <div class ="col order-4 block c" > C</div > <div class ="col order-2 block d" > D</div > </div > <h4 class ="mt-4" > 语义化排序</h4 > <div class ="row" > <div class ="col order-last block a" > A 最后</div > <div class ="col block b" > B 默认</div > <div class ="col order-first block c" > C 最前</div > </div > <h4 class ="mt-4" > 响应式排序:移动端与桌面端顺序不同</h4 > <div class ="row" > <div class ="col-12 col-md-6 order-2 order-md-1 block a" > 图片区域<br > <small > 手机下,桌面左</small > </div > <div class ="col-12 col-md-6 order-1 order-md-2 block b" > 文字区域<br > <small > 手机上,桌面右</small > </div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
7.4 效果解析 第一组虽然 DOM 顺序是 A-B-C-D,但视觉顺序变成了 B-D-A-C;第二组中 C 通过 order-first 排在最前,A 通过 order-last 排在最后;第三组展示了响应式排序:在手机上图片在文字下方(order-2),在桌面端图片在左侧(order-md-1),文字在右侧(order-md-2)。列排序是 Bootstrap 实现“内容优先”响应式设计的重要工具。
八、列嵌套 8.1 概念说明 列嵌套是指在一个 .col-* 内部再放置一个 .row,并在新的 .row 中继续划分列。由于 Bootstrap 的栅格系统基于百分比,嵌套行会把它所在的列当作新的 12 列上下文,因此内部的 .col-6 占据的是父列宽度的 50%,而非整个视口的 50%。
嵌套时需要注意:内部行仍然会有负外边距,因此内容会与父列的边缘对齐,无需额外处理。
8.2 使用场景
复杂卡片 :卡片左侧是缩略图、右侧是文字,右侧文字内部再分两行显示标题和按钮。
仪表盘 :左侧大区域内部再嵌套图表与指标卡片。
混合媒体 :图文列表中,每一项内部再细分图片区、内容区、操作区。
8.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 <!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" > <style > .outer { background : #e8eaf6 ; border : 1px solid #9fa8da ; padding-top : .5rem ; padding-bottom : .5rem ; } .inner-img { background : #c5cae9 ; min-height : 80px ; display : flex; align-items : center; justify-content : center; } .inner-text { background : #e1f5fe ; padding : .75rem ; } </style > </head > <body > <div class ="container mt-4" > <h4 > 外层 6:6,内部继续切分</h4 > <div class ="row" > <div class ="col-md-6 outer" > <div class ="row" > <div class ="col-sm-4 inner-img" > 图</div > <div class ="col-sm-8 inner-text" > <strong > 标题</strong > <p class ="mb-0" > 这里是描述文字,内部再嵌套一行。</p > <div class ="row mt-2" > <div class ="col-6" > <button class ="btn btn-sm btn-primary w-100" > 购买</button > </div > <div class ="col-6" > <button class ="btn btn-sm btn-outline-secondary w-100" > 收藏</button > </div > </div > </div > </div > </div > <div class ="col-md-6 outer" > <div class ="row" > <div class ="col-sm-4 inner-img" > 图</div > <div class ="col-sm-8 inner-text" > <strong > 标题</strong > <p class ="mb-0" > 列嵌套让复杂组件也能保持栅格约束。</p > <div class ="row mt-2" > <div class ="col-6" > <button class ="btn btn-sm btn-primary w-100" > 购买</button > </div > <div class ="col-6" > <button class ="btn btn-sm btn-outline-secondary w-100" > 收藏</button > </div > </div > </div > </div > </div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
8.4 效果解析 页面外层是两列等宽布局,每列内部又嵌套了一个行:左侧占 4/12 放图片,右侧占 8/12 放文字;文字区域内部再嵌套一行,把“购买”和“收藏”按钮平分。由于内部栅格以父列为基准,因此所有比例都是相对于父列而言,整个组件仍然整齐对齐。
九、间距(Gutters) 9.1 概念说明 Gutter 是指列与列之间、行与行之间的空白间距。Bootstrap 5 使用 CSS 变量 --bs-gutter-x 和 --bs-gutter-y 控制水平和垂直间距,默认水平间距为 1.5rem(约 24px),垂直间距为 0。
常用间距类包括:
.g-0:移除所有间距。
.g-1 到 .g-5:小到大间距。
.gx-*:仅控制水平间距。
.gy-*:仅控制垂直间距。
.g-{breakpoint}-*:在指定断点及以上生效的间距控制。
9.2 使用场景
无间距图片墙 :使用 .g-0 让图片紧密排列。
卡片列表 :使用 .g-3 或 .g-4 让卡片之间有舒适呼吸感。
大屏大间距、小屏小间距 :使用 .g-2 g-md-4 实现响应式间距。
9.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 间距 Gutters</title > <link href ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel ="stylesheet" > <style > .cell { background : #fff8e1 ; border : 1px solid #ffe082 ; padding : .5rem ; text-align : center; } </style > </head > <body > <div class ="container mt-4" > <h4 > 默认间距</h4 > <div class ="row" > <div class ="col-4" > <div class ="cell" > A</div > </div > <div class ="col-4" > <div class ="cell" > B</div > </div > <div class ="col-4" > <div class ="cell" > C</div > </div > </div > <h4 class ="mt-4" > 无间距 g-0</h4 > <div class ="row g-0" > <div class ="col-4" > <div class ="cell" > A</div > </div > <div class ="col-4" > <div class ="cell" > B</div > </div > <div class ="col-4" > <div class ="cell" > C</div > </div > </div > <h4 class ="mt-4" > 水平大间距 gx-5</h4 > <div class ="row gx-5" > <div class ="col-4" > <div class ="cell" > A</div > </div > <div class ="col-4" > <div class ="cell" > B</div > </div > <div class ="col-4" > <div class ="cell" > C</div > </div > </div > <h4 class ="mt-4" > 垂直间距 gy-3</h4 > <div class ="row gy-3" > <div class ="col-6" > <div class ="cell" > A</div > </div > <div class ="col-6" > <div class ="cell" > B</div > </div > <div class ="col-6" > <div class ="cell" > C</div > </div > <div class ="col-6" > <div class ="cell" > D</div > </div > </div > </div > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
9.4 效果解析 第一组保留了 Bootstrap 默认的水平间距;第二组 .g-0 让三个单元格紧密相连,没有白边;第三组 .gx-5 加大了水平间距,列与列之间更宽;第四组 .gy-3 在两行之间产生了垂直间距。合理运用 gutter 类,可以在不修改列内容的情况下快速调整版式呼吸感。
十、实战:响应式商品列表页 10.1 概念说明 商品列表页是栅格系统最常见的实战场景之一:它通常包含顶部导航、筛选区、商品卡片网格和底部分页。不同设备上需要呈现不同列数:手机一列、平板两列、桌面四列。通过组合 container、row、col-*、gx-*、响应式断点类,可以快速搭建出整齐、可维护的列表页。
10.2 使用场景
电商首页/分类页 :展示大量商品卡片。
内容聚合页 :如博客列表、视频推荐、图片画廊。
后台数据看板 :指标卡片、图表卡片混排。
10.3 完整 HTML 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 <!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" > <link rel ="stylesheet" href ="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" > <style > .product-card { border : 1px solid #e0e0e0 ; border-radius : .5rem ; overflow : hidden; transition : box-shadow .2s ; } .product-card :hover { box-shadow : 0 .5rem 1rem rgba (0 ,0 ,0 ,.15 ); } .product-image { background : #f5f5f5 ; height : 160px ; display : flex; align-items : center; justify-content : center; color : #9e9e9e ; } .product-body { padding : 1rem ; } .product-title { font-size : 1rem ; font-weight : 600 ; margin-bottom : .5rem ; } .product-price { color : #e53935 ; font-size : 1.1rem ; font-weight : 700 ; } .product-original { color : #9e9e9e ; text-decoration : line-through; font-size : .875rem ; margin-left : .5rem ; } .badge-sale { position : absolute; top : .5rem ; left : .5rem ; } </style > </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 ="#navMenu" > <span class ="navbar-toggler-icon" > </span > </button > <div class ="collapse navbar-collapse" id ="navMenu" > <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 > <li class ="nav-item" > <a class ="nav-link" href ="#" > 我的</a > </li > </ul > </div > </div > </nav > <header class ="bg-primary text-white py-5" > <div class ="container" > <h1 > 夏季清凉特惠</h1 > <p class ="mb-0" > 精选好物,手机端单栏浏览,桌面端四列展示。</p > </div > </header > <main class ="container py-5" > <div class ="row g-3 mb-4" > <div class ="col-12 col-md-4" > <input type ="text" class ="form-control" placeholder ="搜索商品" > </div > <div class ="col-6 col-md-2" > <select class ="form-select" > <option > 全部分类</option > <option > 数码</option > <option > 服饰</option > <option > 家居</option > </select > </div > <div class ="col-6 col-md-2" > <select class ="form-select" > <option > 默认排序</option > <option > 价格从低到高</option > <option > 销量优先</option > </select > </div > </div > <div class ="row g-4" > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <span class ="badge bg-danger badge-sale" > -20%</span > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 轻薄透气T恤</div > <div > <span class ="product-price" > ¥79.00</span > <span class ="product-original" > ¥99.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 便携蓝牙音箱</div > <div > <span class ="product-price" > ¥199.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <span class ="badge bg-warning text-dark badge-sale" > 热卖</span > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 人体工学椅</div > <div > <span class ="product-price" > ¥899.00</span > <span class ="product-original" > ¥1299.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 无线降噪耳机</div > <div > <span class ="product-price" > ¥599.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 智能手表</div > <div > <span class ="product-price" > ¥499.00</span > <span class ="product-original" > ¥699.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <span class ="badge bg-success badge-sale" > 新品</span > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 极简双肩包</div > <div > <span class ="product-price" > ¥159.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 机械键盘</div > <div > <span class ="product-price" > ¥349.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > <div class ="col-12 col-sm-6 col-lg-4 col-xl-3" > <div class ="product-card position-relative" > <div class ="product-image" > <i class ="bi bi-image fs-1" > </i > </div > <div class ="product-body" > <div class ="product-title" > 桌面收纳盒</div > <div > <span class ="product-price" > ¥39.00</span > <span class ="product-original" > ¥59.00</span > </div > <button class ="btn btn-primary btn-sm w-100 mt-2" > 加入购物车</button > </div > </div > </div > </div > <nav class ="mt-5" > <ul class ="pagination justify-content-center" > <li class ="page-item disabled" > <a class ="page-link" href ="#" > 上一页</a > </li > <li class ="page-item active" > <a class ="page-link" href ="#" > 1</a > </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 > </main > <footer class ="bg-light py-4 mt-5" > <div class ="container text-center text-muted" > <p class ="mb-0" > © 2024 优选商城 · Bootstrap 5 栅格系统实战</p > </div > </footer > <script src ="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" > </script > </body > </html >
10.4 效果解析 页面由导航栏、头部横幅、筛选区、商品网格和分页组成。商品卡片使用 col-12 col-sm-6 col-lg-4 col-xl-3:手机端每行一个,平板端每行两个,普通桌面端每行三个,超大屏幕每行四个。筛选区使用 col-12 col-md-4 和 col-6 col-md-2,确保在手机上全宽或半宽、桌面端紧凑排列。整个页面没有手写任何媒体查询,全部通过 Bootstrap 栅格类实现响应式。
十一、本章小结 本章从 Bootstrap 栅格系统的设计思想出发,系统讲解了容器与行的层级关系、12 列栅格的数学原理、列宽类的多种形态、响应式断点的移动优先策略、列偏移与列排序的实现方式、列嵌套的上下文规则,以及 Gutters 间距控制。每一节都配有概念说明、使用场景、完整 Bootstrap 5.3.2 HTML 示例和效果解析,帮助读者把理论知识转化为可运行的代码。
核心要点回顾:
栅格系统基于 12 列 和 Flexbox ,通过类名控制列宽与排列。
容器 → 行 → 列 → 内容 是必须遵守的层级结构。
响应式类遵循 移动优先 原则:小屏默认垂直堆叠,断点及以上才生效指定宽度。
.offset-* 用于精确偏移,.ms-auto/.me-auto 用于弹性对齐。
.order-* 可以重新排列列的视觉顺序,且支持响应式断点。
列嵌套会把父列当作新的 12 列上下文,适合复杂组件。
.gx-*、.gy-*、.g-* 可以灵活控制列间距。
掌握以上内容后,开发者已经可以应对绝大多数页面布局需求。下一章将继续深入 Bootstrap 的组件体系,学习导航、按钮、卡片、模态框等常用组件的使用与定制。