Bootstrap: Sass 定制
最后更新:2026-08-26
1. 本课导读
(1) 前置知识
- 企业站首页综合实战(Lesson 19)
- Node.js 和 npm 包管理器基础用法
- CSS 变量与预处理器概念
(2) 🎯 你将学到
- 搭建 Bootstrap Sass 开发环境
- 通过变量覆盖自定义品牌色、间距和排版
- 按需导入 Bootstrap 组件减小体积
- 扩展自定义工具类
- 编写完整的 Sass 编译脚本
(3) 痛点
Bob 的公司品牌色是紫色(而非 Bootstrap 默认的蓝色),所有按钮、链接和边框都需要改为品牌色——用 CDN 方式无法修改 Bootstrap 的预设样式,每次都要手动覆盖大量 CSS。
(4) 解法
前 19 课使用 CDN 方式引入 Bootstrap,所有样式都是预设的。本课开始进入 Phase 5——通过 Sass 深度定制 Bootstrap,从颜色、间距到组件样式完全掌控。用 Sass 变量覆盖只需改一个 $primary: purple;。
理解方式: CDN 方式 = 吃快餐(快但不可选),Sass 定制 = 自己做饭(慢但可调口味)。Sass 变量就是调料的配方——改一个变量,所有关联组件自动更新。
(5) 收益
Bob 只需修改几个 Sass 变量,所有按钮、链接和边框的颜色自动变为品牌紫色,后续品牌色调整只需改一处即可全局生效,维护成本大幅降低。
2. 环境准备
需要 Node.js 和 npm 环境:
# Create project
mkdir my-bootstrap-project
cd my-bootstrap-project
# Initialize
npm init -y
# Install Bootstrap and its dependencies
npm install bootstrap@5.3.3
npm install -D sass
项目目录结构:
my-bootstrap-project/
scss/
custom.scss # 你的自定义 Sass 文件
dist/
style.css # 编译后的 CSS
index.html
package.json
3. 基本变量覆盖
▶ 示例:基本变量覆盖演示
scss/custom.scss:
// 1. 覆盖 Bootstrap 变量(必须在 import bootstrap 之前)
$primary: #6f42c1; // Purple brand color
$success: #20c997; // Teal
$font-family-sans-serif: 'Inter', system-ui, -apple-system, sans-serif;
$border-radius: 0.5rem; // 8px rounded corners
$enable-shadows: true; // Enable shadow utilities
// 2. 导入完整 Bootstrap
@import "../node_modules/bootstrap/scss/bootstrap";
// 3. 自定义样式
.custom-hero {
background: linear-gradient(135deg, $primary, darken($primary, 15%));
}
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。 编译命令:
npx sass scss/custom.scss:dist/style.css --style compressed
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sass Custom Bootstrap</title>
<link rel="stylesheet" href="dist/style.css">
</head>
<body>
<div class="container py-5">
<button class="btn btn-primary">Primary (Purple)</button>
<button class="btn btn-success">Success (Teal)</button>
<div class="card shadow-sm mt-3 p-4" style="max-width: 400px;">
<h5>Custom Card</h5>
<p class="text-body-secondary">Border-radius is 0.5rem, shadows enabled.</p>
</div>
</div>
</body>
</html>
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
4. 可覆盖的主要变量
(1) 颜色
// Brand colors
$primary: #6f42c1;
$secondary: #6c757d;
$success: #20c997;
$info: #0dcaf0;
$warning: #ffc107;
$danger: #dc3545;
$light: #f8f9fa;
$dark: #212529;
// Custom colors
$custom-color: #ff6b6b;
$theme-colors: map-merge($theme-colors, (
"custom": $custom-color,
));
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。 添加自定义颜色后,可以使用
btn-custom、text-custom、bg-custom。
(2) 间距
$spacer: 1rem; // Base spacer (default 1rem = 16px)
$spacers: (
0: 0,
1: $spacer * 0.25, // 4px
2: $spacer * 0.5, // 8px
3: $spacer, // 16px
4: $spacer * 1.5, // 24px
5: $spacer * 3, // 48px
6: $spacer * 4, // 64px (custom)
7: $spacer * 5, // 80px (custom)
);
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
(3) 排版
$font-family-sans-serif: 'Inter', system-ui, -apple-system, sans-serif;
$font-size-base: 1rem; // 16px
$h1-font-size: $font-size-base * 2.5; // 40px
$headings-font-weight: 600;
$line-height-base: 1.7; // More readable
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
(4) 组件
$border-radius: 0.5rem;
$border-radius-lg: 0.75rem;
$border-radius-sm: 0.25rem;
$btn-border-radius: $border-radius;
$card-border-radius: $border-radius-lg;
$card-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
5. 按需导入组件
完整 Bootstrap 的 CSS 约 250KB(未压缩)。如果只用部分组件,可以只导入需要的模块:
// Required
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/variables-dark";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
// Optional - pick what you need
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/helpers";
// Utilities API (required if using utilities)
@import "../node_modules/bootstrap/scss/utilities/api";
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
6. 工具类扩展
// Add custom utilities
$utilities: map-merge(
$utilities, (
"cursor": map-merge(
map-get($utilities, "cursor"),
(
values: map-merge(
map-get(map-get($utilities, "cursor"), "values"),
(pointer: pointer, grab: grab)
),
),
),
)
);
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
7. 综合实战示例
▶ 示例:完整自定义主题
// scss/custom-theme.scss — Complete custom theme
// ==========================================
// 1. Brand Colors
$primary: #e83e8c; // Pink
$secondary: #6c757d; // Gray
$success: #28a745; // Green
$info: #17a2b8; // Teal
$warning: #ffc107; // Yellow
$danger: #dc3545; // Red
// 2. Typography
$font-family-sans-serif: 'Inter', system-ui, -apple-system, sans-serif;
$font-size-base: 0.9375rem; // 15px
$headings-font-weight: 700;
$line-height-base: 1.7;
// 3. Spacing
$spacer: 1rem;
$spacers: (
0: 0,
1: $spacer * 0.25,
2: $spacer * 0.5,
3: $spacer,
4: $spacer * 1.5,
5: $spacer * 3,
6: $spacer * 4,
7: $spacer * 5,
);
// 4. Border & Shadow
$border-radius: 0.375rem;
$border-radius-lg: 0.5rem;
$border-radius-sm: 0.25rem;
$enable-shadows: true;
// 5. Component Tweaks
$btn-border-radius: 50rem; // Pill buttons
$card-border-color: rgba(0,0,0,0.08);
$card-box-shadow: 0 0.125rem 0.25rem rgba(0,0,0,0.075);
$navbar-dark-color: rgba(255,255,255,0.9);
// 6. Import Bootstrap
@import "../node_modules/bootstrap/scss/bootstrap";
// 7. Custom Extensions
.custom-gradient-bg {
background: linear-gradient(135deg, $primary, darken($primary, 15%));
}
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Theme Demo</title>
<link rel="stylesheet" href="dist/style.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand fw-bold" href="#">Brand</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#nav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="nav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link active" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">About</a></li>
<li class="nav-item"><a class="nav-link" href="#">Pricing</a></li>
</ul>
</div>
</div>
</nav>
<div class="container py-5">
<h1>Custom Bootstrap Theme</h1>
<p class="lead">Brand color: <span class="text-primary fw-bold">Pink (#e83e8c)</span></p>
<div class="d-flex gap-2 mb-4 flex-wrap">
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-info">Info</button>
</div>
<div class="row g-4">
<div class="col-md-4">
<div class="card p-4 shadow-sm">
<h5>Custom Card</h5>
<p class="text-body-secondary">Border-radius: 0.5rem, pill buttons above.</p>
<button class="btn btn-primary rounded-pill">Pill Button</button>
</div>
</div>
<div class="col-md-4">
<div class="card p-4 shadow-sm">
<h5>Spacing Test</h5>
<p class="text-body-secondary">Custom spacers p-6 and p-7 available.</p>
<div class="bg-light p-6 rounded">p-6 (4rem padding)</div>
</div>
</div>
<div class="col-md-4">
<div class="card p-4 shadow-sm bg-primary text-white">
<h5>Gradient BG</h5>
<p class="text-white-50">Using custom-gradient-bg class.</p>
</div>
</div>
</div>
</div>
</body>
</html>
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
▶ 示例:工具类扩展
// scss/utilities-extend.scss
// ==========================================
$primary: #6f42c1;
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
// Extend utilities
$utilities: map-merge(
$utilities, (
// Add cursor utilities
"cursor": map-merge(
map-get($utilities, "cursor"),
(values: map-merge(
map-get(map-get($utilities, "cursor"), "values"),
(pointer: pointer, grab: grab, zoom: zoom-in)
))
),
// Add opacity utilities
"opacity": (
property: opacity,
values: (0: 0, 25: 0.25, 50: 0.5, 75: 0.75, 100: 1),
),
// Custom width steps
"width": map-merge(
map-get($utilities, "width"),
(values: map-merge(
map-get(map-get($utilities, "width"), "values"),
(15: 15%, 35: 35%, 65: 65%)
))
),
)
);
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/utilities/api";
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Extended Utilities</title>
<link rel="stylesheet" href="dist/utilities-extend.css">
</head>
<body>
<div class="container py-4">
<h5>Custom Cursor Utilities</h5>
<div class="d-flex gap-3 mb-4">
<div class="border p-3 cursor-pointer">cursor-pointer</div>
<div class="border p-3 cursor-grab">cursor-grab</div>
<div class="border p-3 cursor-zoom">cursor-zoom</div>
</div>
<h5>Custom Width Steps</h5>
<div class="w-15 bg-primary text-white p-2 mb-1 rounded">w-15</div>
<div class="w-35 bg-success text-white p-2 mb-1 rounded">w-35</div>
<div class="w-65 bg-info text-white p-2 mb-1 rounded">w-65</div>
<h5>Opacity Utilities</h5>
<div class="d-flex gap-2">
<div class="bg-primary text-white p-3 opacity-100 rounded">100%</div>
<div class="bg-primary text-white p-3 opacity-75 rounded">75%</div>
<div class="bg-primary text-white p-3 opacity-50 rounded">50%</div>
<div class="bg-primary text-white p-3 opacity-25 rounded">25%</div>
</div>
</div>
</body>
</html>
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
▶ 示例:Sass 暗色模式
// scss/dark-theme.scss
// ==========================================
$enable-dark-mode: true;
// Light color overrides
$primary: #0d6efd;
$body-bg: #ffffff;
$body-color: #212529;
// Dark mode overrides
$dark-bg: #0d1117;
$dark-surface: #161b22;
$dark-border: #30363d;
$primary-dark: #58a6ff;
@import "../node_modules/bootstrap/scss/bootstrap";
// Dark theme custom styles
[data-bs-theme="dark"] {
--bs-body-bg: #{$dark-bg};
--bs-body-color: #c9d1d9;
--bs-card-bg: #{$dark-surface};
--bs-border-color: #{$dark-border};
}
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sass Dark Mode</title>
<link rel="stylesheet" href="dist/dark-theme.css">
</head>
<body>
<div class="container py-4">
<div class="d-flex justify-content-between mb-4">
<h5>Sass Dark Mode Demo</h5>
<button class="btn btn-outline-primary btn-sm" onclick="toggleTheme()">
<i class="bi bi-moon"></i> Toggle
</button>
</div>
<div class="row g-3">
<div class="col-md-4">
<div class="card p-4">
<h5>Card Title</h5>
<p>This card adapts to the current theme.</p>
<button class="btn btn-primary">Button</button>
</div>
</div>
<div class="col-md-4">
<div class="card p-4">
<h5>Dark Surface</h5>
<p>Custom dark variables applied via Sass.</p>
<div class="alert alert-info">Info alert</div>
</div>
</div>
<div class="col-md-4">
<div class="card p-4">
<h5>Border Colors</h5>
<p>Card border uses custom $dark-border.</p>
<div class="border p-2 rounded">Bordered box</div>
</div>
</div>
</div>
</div>
<script>
function toggleTheme() {
const html = document.documentElement;
const next = html.getAttribute('data-bs-theme') === 'dark' ? 'light' : 'dark';
html.setAttribute('data-bs-theme', next);
}
</script>
</body>
</html>
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
▶ 示例:组件定制
// scss/component-custom.scss
// ==========================================
$primary: #6f42c1;
$border-radius: 0.5rem;
// Card customization
$card-border-radius: 0.75rem;
$card-cap-bg: transparent;
$card-box-shadow: 0 0.5rem 1.5rem rgba(106, 13, 173, 0.1);
$card-border-color: rgba(106, 13, 173, 0.15);
// Button customization
$btn-padding-y-lg: 0.75rem;
$btn-padding-x-lg: 2rem;
$btn-font-weight: 600;
// Navbar customization
$navbar-padding-y: 1rem;
$navbar-brand-font-size: 1.5rem;
// Form customization
$input-border-radius: 0.5rem;
$input-focus-border-color: $primary;
$input-focus-box-shadow: 0 0 0 0.25rem rgba(106, 13, 173, 0.25);
@import "../node_modules/bootstrap/scss/bootstrap";
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Component Customization</title>
<link rel="stylesheet" href="dist/component-custom.css">
</head>
<body>
<div class="container py-4">
<h5>Custom Cards</h5>
<div class="row g-4 mb-5">
<div class="col-md-4">
<div class="card p-4">
<div class="card-body">
<h5 class="card-title">Purple Theme Card</h5>
<p class="card-text">Rounded 0.75rem, purple border, custom shadow.</p>
<a href="#" class="btn btn-primary">Read More</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card p-4">
<div class="card-body text-center">
<h5 class="card-title">Centered Card</h5>
<p class="card-text">Custom card-cap background removed.</p>
<a href="#" class="btn btn-outline-primary">Details</a>
</div>
</div>
</div>
</div>
<h5>Custom Buttons</h5>
<div class="d-flex gap-2 mb-4">
<button class="btn btn-primary btn-lg">Large Custom</button>
<button class="btn btn-primary">Default</button>
<button class="btn btn-primary btn-sm">Small</button>
</div>
<h5>Custom Forms</h5>
<div class="row">
<div class="col-md-6">
<input type="text" class="form-control mb-2" placeholder="Custom input focus...">
<select class="form-select">
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</div>
</div>
</body>
</html>
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
(1) Sass 编译流程
graph LR
A[custom.scss<br/>变量覆盖 + 自定义样式] --> B[sass 编译器]
C[bootstrap/scss/] --> B
B --> D[style.css<br/>完整编译]
D --> E[PurgeCSS]
E --> F[style.min.css<br/>仅保留使用到的 class]
F --> G[浏览器加载]
H[--watch 模式] -.-> B
I[--style compressed] -.-> D
输出: Bootstrap 5.3 样式生效的组件效果(如按钮、卡片、轮播、折叠等),页面默认采用 Bootstrap 默认主题(亮色)和响应式网格。
(2) 核心变量参考表
| 变量名 | 默认值 | 作用 | 影响范围 |
|---|---|---|---|
$primary |
#0d6efd |
主题主色 | 按钮、链接、背景、边框 |
$font-size-base |
1rem |
基础字号 | 全局正文大小 |
$spacer |
1rem |
间距基准值 | p-* m-* gap-* 全部间距 |
$border-radius |
0.375rem |
基础圆角 | 按钮、卡片、输入框 |
$enable-shadows |
true |
启用阴影 | shadow-* 工具类 |
$enable-dark-mode |
true |
暗色模式 | data-bs-theme 支持 |
$font-family-sans-serif |
系统字体栈 | 字体族 | 全局正文字体 |
(3) 组件变量前缀表
| 组件 | 变量前缀 | 示例变量 |
|---|---|---|
| 按钮 | $btn-* |
$btn-border-radius $btn-padding-y |
| 卡片 | $card-* |
$card-border-radius $card-box-shadow |
| 导航栏 | $navbar-* |
$navbar-padding-y $navbar-dark-color |
| 表单 | $input-* |
$input-border-radius $input-focus-box-shadow |
| 模态框 | $modal-* |
$modal-backdrop-bg $modal-content-border-radius |
| 表格 | $table-* |
$table-bg $table-striped-order |
| 提示框 | $alert-* |
$alert-border-radius $alert-link-font-weight |
(4) 构建工具对比表
| 工具 | 用途 | 配置难度 | 与 Bootstrap 搭配 | 推荐场景 |
|---|---|---|---|---|
sass (Dart Sass) |
编译 SCSS 到 CSS | ⭐ | 官方推荐 | 简单项目、仅需 Sass |
| Webpack | 模块打包 + Sass 编译 | ⭐⭐⭐ | 常用 | 大型 SPA 项目 |
| Vite | 快速构建 + Sass 编译 | ⭐⭐ | 推荐 | 现代前端项目 |
| Parcel | 零配置构建 | ⭐ | 可用 | 快速原型、小型项目 |
| Gulp | 任务运行器 | ⭐⭐⭐ | 经典搭配 | 传统项目、多任务流程 |
❓ 常见问题
node-sass 或 sass 版本是否与 Bootstrap 5.3 兼容。推荐使用 sass(Dart Sass)。编译命令用 npx sass 而非全局安装。:root 中覆盖 --bs-primary、--bs-border-radius 等即可,无需编译工具。但 Sass 方式更灵活(可运算、循环、自定义函数)。@import bootstrap 之前定义。Sass 变量的作用域是顺序相关的——先定义、后使用才生效。_variables.scss 中覆盖;(3) custom.scss 在 @import 前覆盖;(4) @import 后自定义样式。特别注意:CSS 变量(--bs-primary)优先级高于 Sass 变量,可用 :root { --bs-primary: red; } 在不重新编译的情况下覆盖。📖 小节
- Sass 定制流程:安装 npm → 创建
custom.scss→ 覆盖变量 → 导入 Bootstrap → 编译 - 可覆盖的颜色、间距、排版、组件圆角等核心变量
- 按需导入组件缩小文件体积
- 编译命令:
npx sass scss/custom.scss dist/style.css
📝 作业
- ⭐ 创建一个使用 Bootstrap Sass 的项目:将品牌色设为
#e83e8c(粉色),按钮圆角设为0.25rem,基础字号设为15px。 - ⭐⭐ 按需导入组件:只导入 grid、buttons、cards、forms、navbar 五个模块,编译后对比完整 Bootstrap 的体积差异。
- ⭐⭐⭐ 自定义间距:添加
spacer-6= 4rem 和spacer-7= 6rem,验证p-6、mt-7是否生效。
上一课: 综合实战:企业站首页 · 下一课: 暗色模式