Bootstrap5-遗失的指南-全-
Bootstrap5 遗失的指南(全)
原文:
zh.annas-archive.org/md5/b7dab63b1d5fb1d6f47ec40f090f22d4译者:飞龙
前言
Bootstrap 是世界上最受欢迎的前端 UI 工具包之一,它提供了使用组件、实用工具、JavaScript 插件等构建响应式网站的易于使用和现成的解决方案。您可以使用 Sass 定制 Bootstrap 5,以实现独特的外观布局,脱颖而出。学习如何定制 Bootstrap 5 使开发者能够创建出独特且不似 Bootstrap 的东西。
本书面向对象
本书旨在为熟悉 HTML 并已有一定 Bootstrap 版本 4 或 5 使用经验的 UI 设计师和开发者编写。这包括使用 Bootstrap 的前端和后端开发者,他们可能不知道如何编写 CSS,但对 HTML 了解足够。
默认 Bootstrap 文件的经验用户通过学习定制和其他高级功能,也可以从这本书中受益。
本书不会教授如何使用默认 Bootstrap 5 组件编写用户界面的基础知识。相反,本书是关于以各种方式定制 Bootstrap 5。
本书涵盖内容
第一章,为什么要定制 Bootstrap 以及如何定制,探讨了为什么我们想要定制 Bootstrap 5,可以定制什么(最重要的定制部分是什么),以及如何进行定制。
第二章,使用和编译 Sass,介绍了 Sass 是什么,我们将了解其特性和优势,如何使用它,如何将其编译成常规 CSS,以及 Bootstrap 5 使用的 Sass 功能。
第三章,下载和探索 Bootstrap 5 Sass 文件,展示了如何下载 Bootstrap 5,然后更详细地探讨了 Bootstrap 5 Sass 文件和 Sass 变量,包括它们的结构。
第四章,Bootstrap 5 全局选项和颜色,深入探讨了如何单独导入 Bootstrap 5 Sass 部分文件,如何更改全局选项,以及如何定制颜色。
第五章,定制各种 Bootstrap 5 元素,探讨了如何定制 Bootstrap 5 元素的视觉样式:布局、内容、表单、组件、辅助工具和实用工具。
第六章,理解和使用 Bootstrap 5 实用 API,探讨了如何使用实用 API 生成和添加新的简单和复杂实用工具,以及如何覆盖、修改和删除现有的实用工具。
第七章,使用默认 Bootstrap 5 元素创建网站,更详细地探讨了我们将要创建的网站,包括页面设置的描述、全局模块的描述以及页面类型的描述。
第八章,使用 Bootstrap 5 变量、实用 API 和 Sass 定制网站,展示了如何通过设置一些全局选项、定义自己的颜色、更改各种 Bootstrap 5 元素的样式以及使用实用 API 来定制我们的网站。
第九章,使用 JavaScript 增强网站交互功能,通过添加不同的交互功能,使用基于 JavaScript 的 Bootstrap 5 组件以及自定义 JavaScript 来改进我们的网站感觉。
第十章,使用 Bootstrap 5 与高级 Sass 和 CSS 功能,探讨了与 Bootstrap 5 相关的 Sass 和 CSS 高级功能,包括如何使用 Sass 混入、函数和扩展,如何使用 CSS 自定义属性,以及如何使用 RFS 插件。
第十一章,使用 Bootstrap 5 与高级 JavaScript 功能,探讨了可以与 Bootstrap 5 交互组件一起使用的 JavaScript 高级功能,包括初始化、选项、方法和事件。
第十二章,优化 Bootstrap 5 CSS 和 JavaScript 代码,深入探讨了如何通过指定我们使用的组件和删除未使用的辅助工具和实用程序来优化编译后的 CSS,以及如何使用模块打包器来优化 JavaScript 并最小化编译后的 CSS 和打包的 JavaScript。
为了充分利用本书
您需要有一些使用 Bootstrap 5(或可能是 Bootstrap 4)创建用户界面的经验。这意味着您应该知道如何使用 HTML 和所有正确的 Bootstrap 5 类和属性来创建各种 Bootstrap 5 组件,或者至少了解这一切是如何工作的。

如果您使用的是本书的数字版,我们建议您自己输入代码或从本书的 GitHub 仓库(下一节中有一个链接)获取代码。这样做将帮助您避免与代码复制和粘贴相关的任何潜在错误。
下载示例代码文件
您可以从 GitHub 下载本书的示例代码文件,网址为github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide。如果代码有更新,它将在 GitHub 仓库中更新。
我们还提供了一些来自我们丰富的图书和视频目录的代码包,可在github.com/PacktPublishing/找到。查看它们!
下载彩色图像
我们还提供了一份包含本书中使用的截图和图表彩色图像的 PDF 文件。您可以从这里下载:packt.link/yXP75。
使用的约定
本书使用了多种文本约定。
文本中的代码: 表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。以下是一个示例:“我们首先导入一些配置文件,这样我们就可以使用$spacer变量作为其他变量的值,我们将在之后立即设置这些变量。”
代码块设置如下:
// Required
@import "../bootstrap/scss/functions";
@import "../bootstrap/scss/variables";
@import "../bootstrap/scss/maps";
@import "../bootstrap/scss/mixins";
@import "../bootstrap/scss/root";
当我们希望您注意代码块中的特定部分时,相关的行或项目将以粗体显示:
// Modified variables
$breadcrumb-bg: $gray-300;
$breadcrumb-border-radius: $spacer;
$breadcrumb-padding-y: $spacer;
$breadcrumb-padding-x: $spacer;
$breadcrumb-item-padding-x: $spacer;
$breadcrumb-divider: quote("·");
任何命令行输入或输出都应如下所示:
npm install bootstrap
粗体:表示新术语、重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词以粗体显示。以下是一个示例:“页面标题全局模块用于所有页面,除了主页和产品页面。”
小贴士或重要注意事项
它看起来像这样。
联系我们
我们始终欢迎读者的反馈。
发送邮件至 customercare@packtpub.com 并在邮件主题中提及书名。
勘误:尽管我们已经尽最大努力确保内容的准确性,但错误仍然可能发生。如果您在这本书中发现了错误,我们将非常感激您向我们报告。请访问 www.packtpub.com/support/errata 并填写表格。
发送邮件至 copyright@packt.com 并附上材料的链接。
如果您有兴趣成为作者:如果您在某个领域有专业知识,并且您有兴趣撰写或为书籍做出贡献,请访问 authors.packtpub.com.
分享您的想法
一旦您阅读了《缺失的 Bootstrap 5 指南》,我们非常想听听您的想法!请点击此处直接进入此书的亚马逊评论页面并分享您的反馈。
您的评论对我们和科技社区都非常重要,并将帮助我们确保我们提供高质量的内容。
第一部分 – 使用 Sass 自定义 Bootstrap 5
在本部分,我们首先会学习为什么要自定义 Bootstrap 以及如何自定义。然后,我们将学习如何使用和编译 Sass,特别关注 Bootstrap 5 使用的 Sass 特性。之后,我们将深入探索 Bootstrap 5 的 Sass 文件,学习如何更改全局选项,定义调色板,自定义各种 Bootstrap 5 元素,以及以各种方式使用实用 API。
本部分包括以下章节:
-
第一章, 为什么要自定义 Bootstrap 以及如何自定义
-
第二章, 使用和编译 Sass
-
第三章, 下载和探索 Bootstrap 5 Sass 文件
-
第四章, Bootstrap 5 全局选项和颜色
-
第五章, 自定义各种 Bootstrap 5 元素
-
第六章, 理解和使用 Bootstrap 5 实用 API
第一章:第一章: 为什么以及如何自定义 Bootstrap
Bootstrap 是一个开源的前端框架,用于快速设计、开发和自定义响应式、移动优先的网站。它具有灵活的网格系统,丰富的预构建可访问和交互式组件,以及许多有用的辅助工具和实用程序。
Bootstrap 为其所有组件提供了预定义的 CSS 样式。这些样式涵盖了从字体和颜色到大小和间距,以及断点、网格系统的选项等。Bootstrap 5 可以直接使用默认样式,但也以不同的方式进行了自定义。
在本章中,您将学习何时想要自定义 Bootstrap,可以自定义什么(以及最重要的自定义部分),以及如何进行自定义。在开始自定义 Bootstrap 之前了解这些内容很重要,因为这将使您更好地准备自定义正确的元素并选择正确的自定义方法。
在本章中,我们将涵盖以下主要主题:
-
我们应该在何时自定义 Bootstrap
-
可以自定义哪些元素?
-
我们如何自定义 Bootstrap 5
-
使用三种不同方法自定义的组件示例
-
使用自定义版本的 Bootstrap 5 的用户界面示例
Bootstrap 版本
本书以 Bootstrap 的最新版本 v5.2.0 为编写目标,本书中一般称为 Bootstrap 5。本书中描述的一些功能和技巧也可能适用于 Bootstrap 4,但可能不适用于 Bootstrap 3。
技术要求
- 用于预览示例的代码编辑器和浏览器
您可以在 GitHub 上找到本章的代码文件,网址为 github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide
我们应该在何时自定义 Bootstrap
当 Bootstrap 与预编译样式表一起使用时,它包含了所有与 Bootstrap 相关的默认颜色、字体、间距等。当您在自己的项目中使用这些样式时,除非您更改这些样式,否则项目看起来不可避免地会像 Bootstrap。如果您正在创建个人项目或内部使用项目,这可能不是问题。但如果你有特定的品牌指南,你的客户或用户通过这些指南来识别你,你可能需要更改这些样式以匹配你的品牌风格。由于 Bootstrap 在互联网上非常流行和广泛使用,有些人可能会识别默认的 Bootstrap 样式,除非您更改它们。这可能会对用户体验产生负面影响,因此对于专业用途,强烈建议自定义默认的 Bootstrap 样式。
可以自定义哪些元素?
Bootstrap 5 可以以多种方式轻松自定义。您可以在所有组件中自定义各种选项,如排版、颜色、间距、尺寸、边框半径、阴影等,还可以单独自定义所有不同的组件。您还可以以许多不同的方式自定义辅助工具和实用工具。无疑,最重要的自定义元素是调色板和排版,以确保它们与您的品牌相匹配。然后,其他方面可以进一步自定义,以符合您当前的品牌指南,或者只是将您的用户界面与使用默认 Bootstrap 样式的所有网站区分开来。
JavaScript 行为也可以自定义
您通常想自定义 Bootstrap 的样式,如前所述;然而,启用 JavaScript 的组件的行为也可以从默认值更改。虽然这对您的品牌感知并不重要,但它可能也是您需要考虑更改的内容。
我们如何自定义 Bootstrap 5
Bootstrap 5 可以使用三种不同的方法进行自定义:
-
直接编辑编译后的 Bootstrap CSS
-
用您自己的自定义样式覆盖 Bootstrap CSS
-
使用 Sass 自定义默认样式
现在我们将简要介绍这些方法。
Sass 是什么?
Syntactically Awesome Style Sheets (Sass) 是一种预处理器脚本语言,它被解释并编译成 层叠样式表 (CSS)。Sass 通过变量、嵌套、部分、函数等扩展了 CSS 的默认功能。我们将在 第二章,使用和编译 Sass 中了解更多关于 Sass 的内容。
方法 1 – 直接编辑编译后的 Bootstrap CSS
您可以直接编辑编译后的 Bootstrap CSS 来实现所需的样式。这可能会相当复杂,具体取决于您想更改的内容,但最重要的是,这将使更新 Bootstrap 变得困难,因为如果您想更新到它的较新版本,您需要重新做出所有更改。这种方法不推荐使用。
方法 2 – 用您自己的自定义样式覆盖 Bootstrap CSS
您可以选择简单地用自己的自定义样式覆盖 Bootstrap CSS,但这会增加总 CSS 代码的大小,如果您想更改默认样式的许多方面,可能需要做很多工作。当更新到 Bootstrap 5 的新版本时,这种方法比上述第一种方法更容易维护,但如果 Bootstrap 5 中添加了新的组件或实用工具,这些将需要根据您的设计需求手动覆盖。如果您只需要更改调色板或出于某种原因无法使用 Sass 编译器来处理 Bootstrap 的原始源代码,这种方法可能适合您。然而,对于这本书,我们将学习如何使用 Sass 来自定义 Bootstrap 5。
方法 3 – 使用 Sass 自定义默认样式
如果您想要最大程度的控制和可能性,您应该使用 Sass 定制 Bootstrap。这需要一个 Sass 编译器,一些 Sass 语言的了解,以及 Bootstrap Sass 文件的知识。所有这些内容都将在接下来的两章中进行解释和演示。
使用 Sass 的一些优点是可以更改全局设置,只需在一个地方修改使用的颜色调色板和字体排印,并且可以轻松地定制组件。此外,它的工作方式也更加容易和快捷,而且编译后的文件大小可以优化以反映实际使用的元素和功能。出于这些原因,这是推荐用于定制 Bootstrap 5 的方法。
现在我们已经了解了我们可以定制 Bootstrap 的各种方法,让我们看看一个示例组件,它使用前面提到的三种不同方法之一进行定制。
使用三种不同方法定制的组件示例
在本节中,我们将看到如何使用上一节中解释的三个不同方法获得相同的视觉样式。我们将定制看起来像这样的 Bootstrap 默认 面包屑 组件:

图 1.1 – 默认的面包屑组件
我们将添加灰色背景色,所有角落的圆角,以及所有边框的填充。我们还将增加面包屑项的水平填充,并更改分隔符。定制版本的面包屑组件将看起来像这样:

图 1.2 – 定制的面包屑组件
无论您使用哪种方法来定制样式,此组件的 HTML 都大致相同。HTML 如下所示:
<nav aria-label="Breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item"><a href="#">Sports</a></li>
<li class="breadcrumb-item"><a href="#">Ball games</a>
</li>
<li class="breadcrumb-item active"
aria-current="page">Baseball</li>
</ol>
</nav>
前两种方法使用纯 CSS,不需要进一步解释。最后一个示例基于 Sass,如果您不熟悉 Sass,可能不太容易理解。然而,它包含在本章中,以展示使用这三种方法实现相同样式所需的代码差异。在下一章中,我将给出 Sass 的一般介绍以及 Bootstrap 如何使用 Sass。
方法 1 – 直接编辑编译后的 Bootstrap CSS
在以下内容中,我们看到的是编译和未压缩的 Bootstrap CSS 文件(bootstrap.css – 行 4494-4525)中找到的面包屑组件 CSS 的略微编辑版本。我们需要对这段代码进行修改以获得我们想要的特定样式,新属性用 + 符号突出显示,属性更改用 * 符号突出显示:
part-1/chapter-1/customization-methods/editing-css/css/bootstrap.css
.breadcrumb {
--bs-breadcrumb-padding-x: 0;
--bs-breadcrumb-padding-y: 0;
--bs-breadcrumb-margin-bottom: 1rem;
--bs-breadcrumb-bg: ;
--bs-breadcrumb-border-radius: ;
--bs-breadcrumb-divider-color: #6c757d;
--bs-breadcrumb-item-padding-x: 0.5rem;
--bs-breadcrumb-item-active-color: #6c757d;
display: flex;
flex-wrap: wrap;
padding: var(--bs-breadcrumb-padding-y)
var(--bs-breadcrumb-padding-x);
margin-bottom: var(--bs-breadcrumb-margin-bottom);
font-size: var(--bs-breadcrumb-font-size);
list-style: none;
* background-color: var(--bs-gray-300);
* border-radius: 1rem;
+ padding: 1rem;
}
.breadcrumb-item + .breadcrumb-item {
* padding-left: 1rem;
}
.breadcrumb-item + .breadcrumb-item::before {
float: left;
* padding-right: 1rem;
color: var(--bs-breadcrumb-divider-color);
* content: var(--bs-breadcrumb-divider, "·");
}
.breadcrumb-item.active {
color: var(--bs-breadcrumb-item-active-color);
}
面包屑组件的分隔符是通过 ::before 伪元素和 content 属性添加的,如前所述。我们将更改 --bs-breadcrumb-divider CSS 自定义属性之后的回退值,因为 Bootstrap 没有定义它。或者,我们可以在 HTML 中定义 CSS 自定义属性来更改分隔符,如下所示:
<nav aria-label="Breadcrumb"
style="--bs-breadcrumb-divider: '·';">
还可以直接将我们的新分隔符作为 content 属性的值添加,如下所示:
content: '·';
我们将在第十章“使用高级 Sass 和 CSS 功能的 Bootstrap 5”中学习更多关于如何使用 CSS 自定义属性的内容。
方法 2 – 使用您自己的自定义样式覆盖 Bootstrap CSS
在这里,我们看到我们需要添加到页面中的自定义 CSS,以覆盖之前示例中显示的相同属性值:
part-1/chapter-1/customization-methods/overwriting-css/css/style.css
.breadcrumb {
background-color: var(--bs-gray-300);
border-radius: 1rem;
padding: 1rem;
}
.breadcrumb-item + .breadcrumb-item {
padding-left: 1rem;
}
.breadcrumb-item + .breadcrumb-item::before {
padding-right: 1rem;
content: '·';
}
如果您将此示例与上一个示例进行比较,您将看到我们正在添加/覆盖与之前添加/更改的完全相同的属性/值。
为了使这可行,请记住在 HTML 文件的 <head> 中在 Bootstrap 样式表之后引用您的样式表,如下所示:
part-1/chapter-1/customization-methods/overwriting-css/index.xhtml
<link rel="stylesheet" href="../../../../bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
方法 3 – 使用 Sass 自定义默认样式
现在,我们将看到自定义 Bootstrap 的推荐方法,即使用新的 Bootstrap 变量的值编译 Sass 样式。这将给我们带来我们想要的视觉输出。
我们首先导入一些配置文件,以便我们可以使用 $spacer 变量作为其他变量的值,我们将立即设置这些变量。
在设置这些变量之后,我们将按照默认顺序导入一些其他必要的 Bootstrap 文件,最后,我们将导入面包屑组件。由于我们只关注此示例中需要包含的绝对必要的文件,因此我们无法使用生成的样式表中的其他 Bootstrap 组件、实用工具等:
part-1/chapter-1/customization-methods/using-sass/scss/bootstrap.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Modified variables
$breadcrumb-bg: $gray-300;
$breadcrumb-border-radius: $spacer;
$breadcrumb-padding-y: $spacer;
$breadcrumb-padding-x: $spacer;
$breadcrumb-item-padding-x: $spacer;
$breadcrumb-divider: quote("·");
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/breadcrumb";
此 Sass 需要由预处理器编译,我们将在下一章学习如何进行此操作。
如果我们将三种不同方法的代码进行比较,我们可以看到方法 3 是最简单且最容易理解的。我们只需声明一些易于理解的变量的值,而无需使用任何 CSS 选择器来完成此操作。这也可以用于 Bootstrap 的未来版本。方法 1 需要您每次想要使用 Bootstrap 5 的新版本时再次编辑编译后的 Bootstrap CSS,而方法 2,如果类名或 HTML 结构发生变化,代码可能需要为 Bootstrap 的未来版本进行更改。
使用 Bootstrap 5 定制版本的用户界面示例
在本节中,我们将看到四个使用 Bootstrap 5 定制版本的用户界面示例。对于每个示例,我们首先将看到使用默认 Bootstrap 5 样式的用户界面截图,然后是使用定制版本的 Bootstrap 5 的用户界面截图。随后将列出所进行的定制。我们将从一个简单的 UI 元素示例开始,以便更好地看到实际的变化,然后查看三个不同的全页示例。所有截图以及完整的定制示例都可以在本书的配套代码中找到,位于以下文件夹:part-1/chapter-1/example-user-interfaces/。我建议你在浏览这些示例和定制列表时查看这些内容,以便更好地理解实际的变化。
卡片组件
以下第一个示例,是一个 Bootstrap 5 的 card 组件。在组件内部,我们使用了 nav 和 list group 组件:

图 1.3 – 使用默认 Bootstrap 5 样式的卡片组件

图 1.4 – 使用 Bootstrap 5 定制版本的卡片组件
在此示例中,对以下 Bootstrap 5 进行了定制:
-
修改了全局设置,包括主要颜色、基本字体大小、标题和字体粗细
-
修改了卡片组件的颜色、背景颜色、字体大小、填充、边距、边框宽度和边框半径
-
修改了导航组件的填充
-
修改了列表组组件的颜色、背景颜色和填充
论坛
以下第二个示例,是从一个 在线论坛 模板中提取的常见论坛 UI。它使用了表格和各种 Bootstrap 5 组件,包括按钮、面包屑、徽章、下拉菜单和分页。

图 1.5 – 使用默认 Bootstrap 5 样式的论坛 UI

图 1.6 – 使用 Bootstrap 5 定制版本的论坛 UI
在此示例中,对以下 Bootstrap 5 进行了定制:
-
修改了全局设置,包括主要颜色、信息颜色和正文背景颜色
-
移除了链接的下划线
-
移除了所有边框半径
-
修改了输入元素的后台颜色
-
修改了表格的颜色、填充和边框
-
修改了按钮的水平填充
-
修改了分页的水平填充
-
修改了徽章的填充并添加了文本转换
联系页面
以下第三个例子,是一个从小型企业网站模板中提取的联系页面。它包含各种 Bootstrap 5 表单元素,包括输入组、文本输入、下拉菜单、文本区域和按钮。它还使用比例辅助类嵌入具有正确宽高比的 Google Maps 地图。

图 1.7 – 使用默认 Bootstrap 5 样式的联系页面 UI

图 1.8 – 使用定制版 Bootstrap 5 的联系页面 UI
在本例中,已对以下 Bootstrap 5 进行了进一步定制:
-
更改了主要和正文文本的全局设置
-
移除了按钮、下拉菜单、选择元素和输入元素上的边框半径
-
更改了输入组附加组件的颜色
-
将“4x3”比例辅助器更改为“3x2”
-
更改了标题的字体粗细和边距
投资组合
以下第四个也是最后一个例子,是一个从投资组合模板中提取的投资组合项目页面。它包含一个轮播图、图像缩略图和多种类型的排版。

图 1.9 – 使用默认 Bootstrap 5 样式的投资组合项目 UI

图 1.10 – 使用定制版 Bootstrap 5 的投资组合项目 UI
在本例中,已对以下 Bootstrap 5 进行了定制:
-
更改了主要和浅色全局设置
-
使用 Bootstrap 5 颜色函数生成主要颜色的较暗变体
-
使用全局选项禁用了所有元素的边框半径
-
增加了
xxl断点的容器最大宽度 -
减少了网格间距宽度
-
更改了标题和低亮度的颜色
-
更改了用于小文本的字体大小
-
更改了导航栏的颜色和字体大小
-
更改了轮播图的指示器
-
更改了图像缩略图的边框
-
更改了图注的颜色和字体大小
本书中的更多定制
前面的四个例子仅展示了不同定制化的视觉影响以及变化的简要描述。在第三章,“下载和探索 Bootstrap 5 Sass 文件”,我们将学习制作类似变化所需的代码。稍后,在本书的第二部分中,我们将创建一个完整的网站项目的完全定制示例。
摘要
在本章中,我们学习了何时应考虑定制 Bootstrap,我们可以定制哪些元素,以及如何进行定制。我们还看到了四个不同的 Bootstrap 5 定制示例。我们现在更好地准备了对正确的元素进行定制并选择正确的定制方法。
在下一章中,你将学习 Sass。你将了解它的特性和优势,如何使用它,以及最后但同样重要的是,如何将其编译成浏览器可以解析的常规 CSS。
第二章:第二章: 使用和编译 Sass
本章是 Sass 的介绍。如果你是 Sass 的初学者,你绝对应该阅读这一章来学习 Sass 的基础知识,Bootstrap 样式就是用 Sass 编写的。如果你已经熟悉 Sass,你可以跳过这一章,但我仍然建议你查看 Bootstrap 使用的 Sass 功能 和 Bootstrap 开发者最重要的 Sass 功能 部分。这将为你开始下一章关于自定义 Bootstrap 做好准备。
在本章中,我们将涵盖以下主要内容:
-
Sass 是什么?
-
Sass 语法
-
Sass 功能
-
Bootstrap 使用的 Sass 功能
-
Bootstrap 开发者最重要的 Sass 功能
-
编译 Sass
技术要求
-
要预览示例,你需要一个代码编辑器
-
要将 Sass 编译成 CSS,你需要以下任何一个:
-
Node.js,如果你更喜欢使用终端(Mac)或命令提示符(Windows)的命令行界面(CLI)
-
Scout-App,如果你更喜欢图形用户界面(GUI)
-
Visual Studio Code,如果你更喜欢使用 Visual Studio Code 市场上的扩展
-
我将在本章中解释所有这些方法。
你可以在 GitHub 上找到本章的代码文件,链接为 github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide。
Sass 是什么?
Sass 是 Syntactically Awesome Style Sheets 的缩写。它是一种特殊的样式表语言,称为预处理器脚本语言,它扩展了 CSS 的默认功能。这使得你可以在代码中使用类似 JavaScript 的逻辑和功能,例如 变量、嵌套、混入、继承、部分、函数、数学运算等。所有这些都有助于你通过自动化重复性任务、减少错误数量、创建可重用代码片段等方式编写更健壮、更易于维护的代码。Sass 的语法类似于 CSS,但 Sass 文件在浏览器中渲染之前需要编译成常规 CSS。这可以通过不同的工具完成,我们将在本章后面了解更多关于这些工具的信息。
Sass 首次发布于 2006 年,并且仍然由一个庞大的社区积极支持和开发。它是目前最受欢迎和使用的 CSS 预处理器,Less 和 Stylus 是市场上另外两个成熟的 CSS 预处理器。
在下一节中,我们将查看 Sass 语法。
Sass 语法
Sass 支持两种不同的语法:原始缩进 Sass 语法和 SCSS 语法,它基本上是常规 CSS 的超集。SCSS 语法对于初学者来说是最简单的,最受欢迎的,也是 Bootstrap 样式所使用的。它也是我将在整本书中使用的语法。然而,这两种不同的语法都支持 Sass 的相同功能。
原始 Sass 语法与现代 Sass 语法的比较
原始语法使用.sass文件扩展名。它使用缩进来代替花括号来分隔代码块,使用换行符(每次按Enter键时)来分隔代码块内的规则。
缩进语法看起来是这样的:
.link
background-color: #aaa
&:hover
text-decoration: underline
&__icon
color: #fff
现代语法使用.scss文件扩展名。SCSS是Sassy CSS的缩写。它使用花括号来分隔代码块,使用分号来分隔代码块内的规则。
SCSS 语法看起来是这样的:
.link {
background-color: #aaa;
&:hover { text-decoration: underline;}
&__icon {
color: #fff;
}
}
两种语法都会输出以下 CSS:
.link {
background-color: #aaa;
}
.link:hover {
text-decoration: underline;
}
.link__icon {
color: #fff;
}
如你所见,它们很相似。但 SCSS 允许你使用分号和花括号以与 CSS 相同的方式格式化代码,而原始 Sass 语法由于依赖于缩进和换行符,因此需要更严格的格式化。
父选择器
使用 Sass,你可以使用带有井号符号的父选择器,&。这个特殊选择器是由 Sass 发明的,用于嵌套选择器中引用父选择器。无论你嵌套了多少层(嵌套将在本节后面描述),井号都会被父选择器替换。你可以用不同的方式使用它,现在我们将通过一些示例来展示。
添加一个额外的类
如果你想要创建一个更具体的带有两个类的选择器,你可以像下面这样使用井号:
.class-one {
&.class-two {
color: red;
}
}
这将生成以下输出:
.class-one.class-two {
color: red;
}
添加伪类
要为某个选择器编写常见的伪类,你可以这样做:
.link {
&:visited {}
&:hover {}
&:active {}
}
这会编译成以下内容:
.link:visited {}
.link:hover {}
.link:active {}
基于另一个选择器进行限定
你可以通过在另一个选择器后面使用井号来限定选择器。所以,例如,如果你想改变一个元素在另一个元素内部使用时的样式,你可以这样做:
.heading {
.alert & {}
}
这会编译成以下内容:
.alert .heading {}
这条样式规则仅适用于.heading类,当它是.alert类的子类时。
修改井号
你可以通过在另一个选择器后面添加一个字符串来修改井号。以下是一个不同按钮样式的示例:
.button {
&-small {}
&-medium {}
&-large {}
}
这将编译成以下内容:
.button-small {}
.button-medium {}
.button-large {}
这在采用命名方法时非常有用,该方法不是使用组合选择器,而是使用破折号和下划线来创建子选择器或修饰选择器。
现在我们已经了解了 Sass 的两种不同语法和特殊父选择器,我们可以继续学习 Sass 的不同特性。
Sass 特性
在本节中,我们将探讨 Sass 的一些最常用特性。这只是一个简要的介绍,让你熟悉 Sass 代码,而不是一个详细的指南,因为我们不会在本书的整个过程中写很多 Sass 代码。
变量
Sass 变量可以用来存储任何你想要复用的 CSS 值。例如,当需要在一个组件中实现一致的配色方案,并且可能需要在后续过程中更改一个或多个颜色时,变量非常有用。这可以通过简单地更新变量的值来完成。要创建一个变量,你只需将一个值分配给以$符号开头的名称。以下是一个创建和使用变量的示例:
$color-primary: blue;
.button {
background-color: $color-primary;
}
当 Sass 文件被处理时,它会取变量的值并将它们放在常规 CSS 中。生成的 CSS 将看起来像这样:
.button {
background-color: blue;
}
默认值
如果你给一个已经赋值的变量赋值,它将被覆盖。但也可以使用!default标志,仅在变量尚未定义或值为 null 时才给变量赋新值。这在创建 Sass 库(如 Bootstrap)时非常有用,你希望用户在生成 CSS 之前配置变量。如果用户没有配置任何变量,库设置的默认值将被使用。
以下是一个使用变量正常使用且将被覆盖的示例:
$color-primary: blue;
$color-primary: red;
.button {
background-color: $color-primary;
}
这将编译成以下内容:
.button {
background-color: red;
}
按钮的背景颜色变成了红色,因为$color-primary变量的值已被覆盖。
如果你使用!default标志,它将像这样工作:
$color-primary: blue;
$color-primary: red !default;
.button {
background-color: $color-primary;
}
这将编译成以下内容:
.button {
background-color: blue;
}
如我们所见,按钮的背景颜色现在将保持蓝色,因为!default标志不会改变$color-primary变量的值。
嵌套
使用 Sass,你可以嵌套你的 CSS 选择器,并实现与 HTML 相同的视觉层次结构。在嵌套 CSS 选择器时,有很多层级通常被认为是一种不好的做法;使用精心嵌套的 CSS 选择器是使你的代码更易读的好方法。
以例如这个使用无序列表链接创建的导航组件为例:
<nav>
<ul>
<li>
<a>Menu item</a>
</li>
<li>
<a>Menu item</a>
</li>
<li>
<a>Menu item</a>
</li>
</nav>
为了在我们的代码中获得更好的概览,我们可以以下面的方式嵌套 CSS 选择器,以反映我们的 HTML 结构:
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
li {
display: inline-block;
a {
text-decoration: none;
}
}
}
}
这将编译成以下内容:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav ul li {
display: inline-block;
}
nav ul li a {
text-decoration: none;
}
Partials 和导入
Partials 是包含 Sass 代码的小型文件,你可以将其导入到其他 Sass 文件中。这对于将代码组织成不同的部分和模块,以便更好地了解项目非常有用。Sass partial 文件以下划线字符(_)开头,这将防止它生成自己的 CSS 文件。要将 Sass partial 导入到另一个文件中,你应该使用@import规则。你不需要包含文件扩展名,并且可以省略开头的下划线字符。
由于 Sass 的@import规则在编译期间处理——与需要多个 HTTP 请求的常规 CSS @import规则不同——你可以访问 mixins、函数和变量。
在以下示例中,我们将有两个 Sass 部分,_button.scss和_link.scss,以及一个主文件styles.scss,它将导入它们:
第一个部分文件的名称:_button.scss
$color-primary: red;
.button {
background-color: $color-primary;
}
第二个部分文件的名称:_link.scss
$color-link: blue;
.link {
color: $color-link;
}
主文件:styles.scss
@import 'button';
@import 'link';
// other SCSS code here
这将编译成以下内容:
.button {
background-color: red;
}
.link {
color: blue;
}
// other CSS code here
@import正在被弃用
Sass 团队不鼓励使用@import规则。在未来几年内,它将被逐步淘汰,并最终完全移除。相反,应该使用@use规则。Bootstrap 在其 Sass 代码中使用@import规则,这就是为什么我在这里使用它而不是@use。
Mixins
使用 mixin,你可以将你想要在整个项目中重复使用的 CSS 声明组合在一起。mixin 还可以接收参数,允许它们在每次使用时进行自定义。它们使用@mixin规则定义,并使用@include规则在代码中包含。mixin 将样式复制到它们被使用的地方。
简单 mixin
这里是一个没有参数的简单 mixin 示例。这是一个所谓的clearfix mixin,它直接来自 Bootstrap 5 Sass 代码,并且也用于其clearfix辅助工具:
@mixin clearfix {
&::after {
display: block;
content: "";
clear: both;
}
}
.parent-with-floated-child-elements {
@include clearfix;
}
这会编译成以下内容:
.parent-with-floated-child-elements::after {
display: block;
content: "";
clear: both;
}
带参数的 mixin
在这个示例中,我们看到一个简单的网格 mixin。它有一个默认值为true的$grid参数。在 mixin 的定义之后,我们将其包含在两个元素中。第一个将使用默认参数来获取display值(grid),而另一个将使用false作为参数来获取display值(flex):
@mixin grid($grid: true) {
@if $grid {
display: grid;
} @else {
display: flex;
}
}
.row-grid {
@include grid;
}
.row-flex {
@include grid(false);
}
这将编译成以下内容:
.row-grid {
display: grid;
}
.row-flex {
display: flex;
}
扩展
扩展是 Sass 中重复使用 CSS 声明的另一种方法。使用这种方法,你可以在另一个选择器中共享一个选择器的样式。当你将一个类选择器扩展到另一个选择器时,结果是等于将那个类添加到 HTML 元素中。扩展选择器不会像 mixin 那样复制任何样式,而是更新扩展选择器的样式规则,使其也包含扩展选择器的样式。
这里是一个带有边框和内边的简单.alert类的示例。在这个示例内部嵌套了一个修改过的父选择器,它生成.alert-success类,这个类将扩展.alert类并添加背景颜色:
.alert {
border: 1px solid black;
padding: 1rem;
&-success {
@extend .alert;
background-color: green;
}
}
这会编译成以下内容:
.alert, .alert-success {
border: 1px solid black;
padding: 1rem;
}
.alert-success {
background-color: green;
}
如您所见,.alert-success类现在被添加到.alert类的样式声明中。因此,为了澄清,当一个类选择器扩展另一个选择器时,扩展选择器所属的样式现在也将对扩展选择器可用。
运算符
使用运算符,你可以在 CSS 中对不同值进行基本的数学计算。除了基本的数学计算,如加法、减法、乘法和除法之外,你还可以检查各种值之间的关系和相等性,还有更多。
下面是一些基本的数学计算示例,适用于数字和字符串:
.addition {
margin: 10px + 5px;
content: "Hello " + "world!";
}
.subtraction {
margin: 25px - 10px;
}
.multiplication {
margin: 3 * 5px;
}
.division {
margin: (30 / 2) * 1px;
}
这会编译成以下内容:
.addition {
margin: 15px;
content: "Hello world!";
}
.subtraction {
margin: 15px;
}
.multiplication {
margin: 15px;
}
.division {
margin: 15px;
}
使用/进行除法已被弃用
Sass 中的除法使用/*已被弃用,因为它在 CSS 中用作分隔符。相反,应该使用 Sass 内建的math.div()数学模块函数来进行除法,如下所示:math.div(30, 2),结果为15。
函数
你可以创建自己的函数来执行特定的操作,这些操作需要在项目中重复使用。它们通过@function规则创建,并使用@return规则返回一个值。它们使用正常的 CSS 函数语法调用。就像混入一样,函数可以接收参数,允许每次调用时自定义行为。参数在函数内部作为变量可用。
这里有一个简单的函数,它将两个值相加并返回结果。这些值可以是数字或字符串,但在这个例子中,它们将是两个数字:
@function add($a, $b) {
@return $a + $b;
}
.ordered-item {
order: add(1, 2);
}
这会编译成以下内容:
.ordered-item {
order: 3;
}
调用函数时必须指定正确的参数数量,除非你通过为其中一个参数定义默认值来使其变为可选。
如此即可通过将其默认值设为2来使第二个参数变为可选:
@function add($a, $b: 2) {
@return $a + $b;
}
.ordered-item {
order: add(1);
}
这会编译成以下内容:
.ordered-item {
order: 3;
}
特殊值
Sass 支持许多种类的值。其中大部分来自 CSS,而一些则是 Sass 特有的。映射是 Sass 的特殊值之一,用于在列表中关联键和值。映射不是有效的 CSS 值,因此不能单独使用。然而,Sass 提供了各种函数来处理映射。
这里有一个简单的例子,首先定义了一个包含三个键值对的$font-size映射,然后通过使用map-get()函数,并传入映射名称和请求值的键作为参数来获取第三个键的值:
$font-size: (
"small": 12,
"default": 16,
"large": 20
);
.lead-paragraph {
font-size: map-get($font-size, "large");
}
这会编译成以下内容:
.lead-paragraph {
font-size: 20;
}
内建模块
Sass 提供了包含各种函数和混入的内建模块。这些函数最初是全局可用的,但现在应该通过@use规则(少数例外)来加载。其中一些更有用的函数是用于操作颜色值和与基于列表和映射的值一起工作的函数。
这里是如何使用内建颜色模块中的color.scale()函数流畅地缩放颜色属性的示例。在这个例子中,该函数用于将颜色的亮度增加 25%,你可以看到即使使用命名颜色作为参数,这也同样有效:
@use "sass:color";
$color-primary: blue;
.button {
color: $color-primary;
background-color: color.scale($color-primary,
$lightness: 25%);
}
这会编译成以下内容:
.button {
color: blue;
background-color: #4040ff;
}
现在我们已经查看了一些 Sass 的特性,让我们看看 Bootstrap 使用了哪些特性。
Bootstrap 使用的 Sass 特性
这只是对 Bootstrap 使用的 Sass 特性的快速概述。我们将在下一章深入探讨 Bootstrap 是如何构建的。
语法
如前所述,Bootstrap Sass 代码使用 SCSS 语法编写。它还使用&父选择器来处理伪类和状态,以及属性选择器。
部分文件
Bootstrap 5 的 Sass 代码分为 81 个部分和五个文件夹。这些部分随后通过其他部分或常规 SCSS 文件导入。这为 Bootstrap 的所有各个部分提供了一个良好的概览。
变量
变量在 Bootstrap 中被广泛使用。它们用于在组件之间保持视觉一致性,例如颜色、间距等,但它们也以这种方式使用,使得用户在生成 CSS 之前可以轻松地进行配置。
地图
地图在 Sass 库和设计系统中经常被使用。在 Bootstrap 中,它们主要用于配置工具所使用的值。
混合
混合在 Bootstrap Sass 代码中广泛使用。它们用于布局、组件、辅助工具、工具和其他视觉样式。
内置模块
Bootstrap 使用 Sass 的颜色和地图模块。它使用颜色模块中的函数(以及其他包含的颜色函数)来处理与颜色相关的视觉样式,并使用地图模块中的函数来处理用于生成工具的地图值。
现在我们已经了解了 Bootstrap 如何利用 Sass 的各种特性。但是,对于与 Bootstrap 定制化工作的开发者来说,哪些特性最为重要?现在让我们来看看。
对 Bootstrap 开发者来说最重要的 Sass 特性
在定制 Bootstrap 时,以下是一些你将最常使用的 Sass 特性的快速概述。
用于定制的变量
在定制 Bootstrap 时,理解使用 Sass 变量的能力是最重要的特性。你想要做的多数更改都需要你覆盖 Bootstrap 已经使用的变量。
工具 API 的地图
Sass 伴随的特殊地图值与工具 API 结合使用,以生成各种工具类。这可以用来修改或删除现有的工具,或者添加你自己的。我们将在下一章中学习如何使用工具 API。
工具 API
工具 API 是 Bootstrap 5 的内置工具,用于生成不同的工具类。Sass 地图用于为工具 API 提供设置和选项。
混合和扩展用于语义化代码
Bootstrap 有许多由不同 Bootstrap 元素使用的混合,但这些混合也可以在你的代码中使用。混合和 Sass 的扩展功能都可以用来编写更语义化的代码,我们将在第八章中更详细地探讨,使用 Bootstrap 5 变量、工具 API 和 Sass 定制网站。
我们刚刚看到了如何使用 Sass 的一些特性,现在我们将学习如何将 Sass 代码编译成常规 CSS。
编译 Sass
您有多种方式可以编译您的 Sass 代码。如果您是 Sass 的初学者并想尝试语法和功能,您可以使用 Sassmeister 并立即开始。如果您想将 Sass 编译集成到您的开发工作流程中,有几种方法可以实现。我将向您展示三种不同的方法。第一种方法需要您使用 Node.js 和终端或命令提示符,第二种方法使用一个名为 Scout-App 的免费应用程序,第三种方法使用 Visual Studio Code 代码编辑器的扩展。
使用 Sassmeister 进行 Sass 实验
Sassmeister,可在 sassmeister.com 访问,是一个在沙盒环境中实验 Sass 的免费工具。您可以使用 Sass 或 SCSS 语法,选择不同的 Sass 编译器,定义 CSS 输出,等等。本章中的所有示例都可以在 Sassmeister 中看到实际效果。

图 2.1 – Sassmeister Sass 沙盒环境在 sassmeister.com
将 Sass 编译集成到开发工作流程中
在接下来的三个小节中,我将描述将 Sass 编译集成到开发工作流程中的不同方法。对于所有这些方法,我们将使用相同的 HTML 文件和 SCSS 文件。您必须自己创建这些文件并将它们放置在项目文件夹中。
HTML 文件应包含以下代码:
index.xhtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<link rel="stylesheet" href="style.css">
<title>Compiling Sass</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
这是 HTML 文件的基代码,包括一个指向尚未从源 Sass 代码编译的样式的 <link> 标签。如果您在编译之前在浏览器中打开此文件,它将简单地显示 Hello world!。
SCSS 文件应包含以下代码:
style.scss
$color-primary: blue;
h1 {
color: $color-primary;
}
首先,我们在 $color-primary 变量中存储了 blue 颜色。然后,我们使用该变量设置 h1 元素的文本颜色。在编译我们的 Sass 后,我们得到一个包含以下代码的新 CSS 文件:
style.css
h1 {
color: blue;
}
在浏览器中重新加载 HTML 文件后,我们将看到标题的文本颜色现在是蓝色。这表明 Sass 编译按预期工作,并且现在已生成了引用的 CSS 文件。
继续阅读下一部分,了解将 Sass 编译集成到开发工作流程中的不同方法。
使用 Node.js
第 1 步:下载并安装 Node.js
此方法需要您下载并安装 Node.js。为此,您只需访问官方网站 nodejs.org 并从那里下载即可。npm 是与 Node.js 自动安装的默认包管理器。
第 2 步:使用终端或命令提示符导航到您的项目文件夹
现在,打开终端(macOS)或命令提示符(Windows),并使用以下命令导航到您的项目文件夹:
cd [project-folder-path]
方括号不应使用,例如,如下所示:
cd projects/bootstrap/example
从 macOS 的 Finder 拖动你的文件夹
如果你使用 macOS,你可以简单地输入 cd(记得在最后加空格),然后从 Finder 拖动你的文件夹到终端。这将插入正确的文件夹路径。现在,你只需按 Enter 键。
在 Windows 的文件资源管理器中输入 cmd
如果你使用 Windows,你可以在 文件资源管理器 窗口的搜索栏中输入 cmd 快捷方式。按 Enter 键将打开命令提示符中的文件夹。
第 3 步:初始化一个新的 npm 项目
然后,为了初始化一个新的 npm 项目,我们输入以下两个命令之一:
npm init
npm init -y
如果你选择第一个选项(不带 -y 标志),你将被要求输入项目信息。每个步骤都可以通过按 Enter 键跳过,之后也可以编辑所有内容。
如果你选择第二个选项(带 -y 标志),它将自动回答这些问题。这也可以稍后编辑。
运行 npm init 命令后,将生成一个包含你的 npm 项目基本信息的 package.json 文件。它看起来可能像这样:
{
"name": "[the name of your folder]",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
第 4 步:全局安装 Sass
我们现在将在机器上全局安装 Sass npm 包,使其可用于此和其他未来的项目。此包用于将你的 Sass 代码编译为 CSS。输入以下命令:
npm install sass -g
要检查你是否已成功安装 Sass,你可以输入以下命令:
sass --version
你将在你的终端中看到以下内容:
1.43.4 compiled with dart2js 2.14.4
如果你使用 macOS 的终端,并且在尝试安装 Sass 时遇到有关文件权限的错误,你可以尝试添加 sudo 命令,这样完整的命令将是:
sudo npm install sass -g
如果你在 Windows 上遇到类似的问题,可以尝试以管理员身份运行命令提示符。
第 5 步:将 Sass 编译为 CSS
现在,是时候编译你的 Sass 代码了。为此,你使用 sass 命令,后跟输入文件路径(你的 Sass 源文件)和输出文件(你想要用于网站的 CSS 文件),以及任何可选设置:
sass [input-path] [output-path]
或
sass [input-path] [output-path] [settings]
请注意,在先前的命令中,不应使用方括号。
最有用的设置如下:
-
--style=expanded– 生成一个压缩和最小化的 CSS 文件。 -
--no-source-map– 阻止生成源映射文件。此文件将转换后的源映射到原始源,以便浏览器可以在调试器中显示原始内容。 -
--watch– 监视文件中的任何更改并自动重新编译。
如果你添加了多个设置,请记住在它们之间添加空格。
要编译起始模板中包含的 SCSS 文件,你将输入以下命令:
sass style.scss style.css
这将编译 style.scss 中找到的 Sass 代码到 CSS,并在同一文件夹中创建新的 style.css 文件以及 style.css.map 源映射文件。
现在,你可以在浏览器中查看编译后的 Bootstrap CSS 的起始模板。
使用 Scout-App
如果您在编译 Sass 时更喜欢使用 GUI,可以使用免费的Scout-App应用。您可以从scout-app.io下载,并且有适用于 macOS、Windows 和 Linux 的版本。
在首页有一个非常棒的入门视频,我建议您观看以了解该应用的工作原理。您也可以通过以下链接直接在 YouTube 上观看视频:youtu.be/6zA78zMsH9w。

图 2.2 – 官方 Scout-App 网站首页截图
使用 Visual Studio Code 的 Live Sass Compiler 扩展
如果您使用 Visual Studio Code 作为代码编辑器,可以通过 Glenn Marks 的Live Sass Compiler进行安装,然后点击安装:

图 2.3 – Visual Studio Code 扩展标签页中打开的 Live Sass Compiler 扩展截图
您也可以通过以下链接在 Visual Studio Marketplace 上找到此扩展:
marketplace.visualstudio.com/items?itemName=glenn2223.live-sass
在成功安装扩展后,当您打开 SCSS 或 SASS 文件时,需要点击状态栏中的Watch Sass来激活实时 Sass 编译器。完成工作后,只需再次点击相同的按钮即可将其停用。
摘要
本章是为没有先前经验的 Sass 初学者而写的介绍。我们学习了语法和一般特性,还了解了 Bootstrap 使用的特性以及对于 Bootstrap 开发者来说最重要的特性。最后,我们还学习了各种编译 Sass 的方法,无论是简单的实验还是将 Sass 编译集成到开发流程中。
在下一章中,我们将学习如何使用 Sass 自定义 Bootstrap 5。如果您已经阅读了本章,您现在已经为深入 Bootstrap 5 的 Sass 代码做好了充分的准备。
第三章:第三章:下载和探索 Bootstrap 5 Sass 文件
在本章中,我们将首先看到两种不同的方式下载 Bootstrap 5 源代码,然后我们将更深入地查看源代码中的 Bootstrap 5 Sass 文件。我们将学习 Sass 代码是如何被分成各种文件,这些文件是如何结构的,以及这种结构意味着什么。
之后,我们将学习如何导入默认的 Bootstrap 5,最后,我们将了解 Bootstrap 5 的 Sass 变量。
在自定义样式之前熟悉 Bootstrap 5 的 Sass 文件和变量是有用的,因为您将知道在哪里搜索和查找满足您需求的特定变量。您还将了解某些变量和文件之间的依赖关系。
在本章中,我们将介绍以下主题:
-
下载 Bootstrap 5 源代码
-
探索 Bootstrap 5 的 Sass 文件
-
导入默认的 Bootstrap 5
-
探索 Bootstrap 5 变量
技术要求
-
为了预览示例,您需要一个代码编辑器和浏览器。
-
您需要一个 Sass 编译器来编译 Bootstrap 5 Sass 文件到 CSS。请参阅第二章,使用和编译 Sass,了解不同的方法。
您可以在 GitHub 上找到本章的代码文件,地址为github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide
下载 Bootstrap 5 源代码
您可以通过不同的方式下载 Bootstrap 5。在这里,我将向您展示三种方法。
从网站
您可以从getbootstrap.com的官方 Bootstrap 网站,在文档部分的入门部分的下载页面下载 Bootstrap 文件:getbootstrap.com/docs/5.2/getting-started/download。
从那个下载页面,您可以下载 Bootstrap 5 的编译版 CSS 和 JavaScript 文件,或者您可以下载源文件,其中包含所有的 Sass 代码、JavaScript 代码和文档文件。我们想要源文件,所以您应该点击紫色下载源文件按钮来下载一个包含我们所需所有内容的 ZIP 文件。
从 GitHub
Bootstrap 5 的源代码可以从官方 GitHub 仓库github.com/twbs/bootstrap下载。要从那里下载,您首先点击绿色的代码按钮来展开弹出窗口。从那里,您可以使用以下命令获取克隆它的 URL:
git clone https://github.com/twbs/bootstrap.git
或者,您可以直接下载包含所有源代码的 ZIP 文件。
从 NPM
如果您在开发设置中使用 NPM,您可以使用以下命令下载和安装 Bootstrap 5 的最新版本:
npm install bootstrap
它现在将被下载到你的项目的 node_modules 文件夹中。我们将在第十二章优化 Bootstrap 5 CSS 和 JavaScript 代码中看到如何使用 Node.js、NPM 和 Laravel Mix 设置构建过程。
现在我们已经下载了 Bootstrap 5,是时候看看 Sass 文件了。
探索 Bootstrap 5 Sass 文件
在本节中,我们将探索 Bootstrap 5 Sass 文件。这些文件位于下载的 Bootstrap 5 文件中的 scss 文件夹内。我们将查看此文件夹及其子文件夹的内容。
根目录
在 scss 文件夹的根目录中,我们总共有 41 个文件,其中 37 个是 Sass 部分文件,因为它们以下划线开头,剩下的 4 个文件是常规的 SCSS 文件。以下是每个文件的概述,每个文件旁边都有注释:
_accordion.scss (component)
_alert.scss (component)
_badge.scss (component)
_breadcrumb.scss (component)
_button-group.scss (component)
_buttons.scss (component)
_card.scss (component)
_carousel.scss (component)
_close.scss (component)
_containers.scss (layout)
_dropdown.scss (component)
_forms.scss (imports partials from the "forms" folder)
_functions.scss (various custom Bootstrap 5 functions)
_grid.scss (layout)
_helpers.scss (imports partials from the "helpers" folder)
_images.scss (content)
_list-group.scss (component)
_maps.scss (Sass maps for customization)
_mixins.scss (imports partials from the "vendor" and
"mixins" folder)
_modal.scss (component)
_nav.scss (component)
_navbar.scss (component)
_offcanvas.scss (component)
_pagination.scss (component)
_placeholders.scss (component)
_popover.scss (component)
_progress.scss (component)
_reboot.scss (normalization of HTML elements)
_root.scss (CSS custom properties)
_spinners.scss (component)
_tables.scss (content)
_toasts.scss (component)
_tooltip.scss (component)
_transitions.scss (global transitions)
_type.scss (content)
_utilities.scss (settings for utilities)
_variables.scss (Sass variables for customization)
bootstrap-grid.scss (main SCSS file that imports grid and
flex utilities only)
bootstrap-reboot.scss (main SCSS file that imports reboot
styles only)
bootstrap-utilities.scss (main SCSS file that imports
utilities only)
bootstrap.scss (main SCSS file that imports everything)
如您从我的注释中看到的,大多数文件都与 Bootstrap 5 单个部分的样式相关:布局、内容和组件。以下是其他文件的快速说明。
_forms.scss
此文件从 forms 文件夹导入所有 Sass 部分文件;它用于为各种表单元素提供样式。
_functions.scss
此文件包含各种自定义 Bootstrap 5 函数。它主要用于评估变量、映射和混入之间的源代码,但除此之外,你还会找到 tint-color() 和 shade-color() 颜色函数,我们将在本章后面再次提到。
_helpers.scss
此文件从 helpers 文件夹导入所有 Sass 部分文件;它用于为各种辅助类提供样式。
_maps.scss
此文件包含重新分配的 Sass 映射,可以通过覆盖默认 Sass 映射来进行自定义。这将自动更新实用工具等。
_mixins.scss
此文件从 vendor 和 mixins 文件夹导入所有 Sass 部分文件。vendor 文件夹包含 mixins 文件的样式,而 mixins 文件夹包含许多有用的混入(mixins),这些混入被其他文件在其他地方使用。我们将在第十章使用 Bootstrap 5 与高级 Sass 和 CSS 功能中了解更多关于如何充分利用 RFS Sass 插件和 Bootstrap 5 混入的方法。
_reboot.scss
此文件包含用于标准化常见 HTML 元素样式的代码。它不是针对任何类,而是直接针对 HTML 元素。它是 Normalize.css 的分支,其中一些代码已被删除,而一些代码已被添加。Normalize.css 是一个重置样式表,它使浏览器更一致地渲染所有元素。更多关于它的信息可以在官方网站上找到:necolas.github.io/normalize.css/。
_root.scss
此文件用于生成根元素的 CSS 自定义属性,在这种情况下,意味着颜色和基本排版。它主要用于 _reboot.scss 文件,但也有一些在其他地方使用。
_transitions.scss
此文件包含各种组件使用的过渡样式。
_utilities.scss
此文件包含所有工具的设置。这些设置由工具 API 用于生成工具类。你将在第六章,理解和使用 Bootstrap 5 工具 API中了解更多关于工具 API 的内容。
_variables.scss
此文件包含 Bootstrap 5 中跨文件使用的变量列表。你将在第四章**,Bootstrap 5 全局选项和颜色,以及第五章**,定制各种 Bootstrap 5 元素中了解更多关于此文件的内容。
主要 SCSS 文件
在所有的 Sass 部分文件之后,我们有四个主要的 SCSS 文件,它们用于导入 Bootstrap 5 的不同版本。以下是每个文件的快速概述以及它们导入的内容:
-
bootstrap-grid.scss: 仅包含网格系统和弹性工具 -
bootstrap-reboot.scss: 仅包含重置样式 -
bootstrap-utilities.scss: 仅包含辅助工具和工具 -
bootstrap.scss: 所有内容
在这四个文件中,我们只会使用 bootstrap.scss 来导入所有内容,但我们也会使用 bootstrap.scss 内部的修改版本来进行特定的定制和优化。
scss 文件夹还包含以下子文件夹:forms、helpers、mixins、utilities 和 vendor。这些文件夹包含更多的 Sass 部分文件。我已经在描述根文件夹中的 Sass 部分文件时提到了这些文件夹,所以不会进一步详细介绍。通常,所有 Sass 部分文件都应该保持不变,除非你有非常高级和具体的要求。我们在自己的文件中定制 Bootstrap 5,并按原样导入 Bootstrap 5 文件。
导入默认的 Bootstrap 5
在上一章中,我们学习了如何将 Sass 编译为 CSS。为了导入没有定制的默认 Bootstrap 5,我们只需将 bootstrap.scss 文件导入到我们自己的 SCSS 文件中,如下所示:
part-1/chapter-3/import-compile-default-bootstrap/scss/bootstrap.scss
@import "../../../../bootstrap/scss/bootstrap";
在下一章中,我们将学习如何导入一个更高级的定制版本的 Bootstrap 5,其中我们导入 Bootstrap 5 的单个 SCSS 文件,而不是像前面代码中那样导入主文件。
在学习如何以不同的方式定制 Bootstrap 5 之前,我们将更仔细地查看 bootstrap.scss 文件。
探索 bootstrap.scss
bootstrap.scss 文件包含所有将导入各种元素的单个 Sass 部分文件的代码。现在让我们看看这个文件包含什么:
bootstrap.scss
@import "mixins/banner";
@include bsBanner("");
// scss-docs-start import-stack
// Configuration
@import "functions";
@import "variables";
@import "maps";
@import "mixins";
@import "utilities";
// Layout & components
@import "root";
@import "reboot";
@import "type";
@import "images";
@import "containers";
@import "grid";
@import "tables";
@import "forms";
@import "buttons";
@import "transitions";
@import "dropdown";
@import "button-group";
@import "nav";
@import "navbar";
@import "card";
@import "accordion";
@import "breadcrumb";
@import "pagination";
@import "badge";
@import "alert";
@import "progress";
@import "list-group";
@import "close";
@import "toasts";
@import "modal";
@import "tooltip";
@import "popover";
@import "carousel";
@import "spinners";
@import "offcanvas";
@import "placeholders";
// Helpers
@import "helpers";
// Utilities
@import "utilities/api";
// scss-docs-end import-stack
如您从前面的代码中可以看到,bootstrap.scss 文件将导入根 scss 文件夹中的所有 Sass 部分文件,而其中一些文件将导入子文件夹中的 Sass 部分文件。对于某些自定义,在定义自定义更改后导入此文件就足够了,但对于其他自定义,我们需要单独导入 Bootstrap 5 部分文件,并在这些导入之间添加我们自己的自定义更改。在接下来的章节中,我将向您展示何时需要导入整个 bootstrap.scss 文件或单独导入 Bootstrap 5 部分文件。
接下来,让我们简单谈谈 Bootstrap 5 的变量。
探索 Bootstrap 5 的变量
要自定义 Bootstrap 5 的任何元素,您将首先查看 _variables.scss 文件。此文件包含 Bootstrap 5 所使用的所有变量,包括全局选项、颜色、布局、内容(包括排版)、表单、组件、辅助工具和实用工具的变量。因此,例如,要了解组件的哪个部分可以自定义,您只需在 _variables.scss 文件中搜索组件名称。然后,您将找到所有相关变量及其默认值分组在一起。现在,您需要在自己的 Sass 文件中使用这些相同的变量名来更改它。您将在下一章中学习如何确切地做到这一点。
Bootstrap 团队已经仔细地排列了这些变量,因为一些变量引用了其他变量。不同组件的变量出现顺序不是按字母顺序排列的,因此我最好的建议是滚动浏览文件或搜索组件名称。
Bootstrap 5 使用了总共 886 个变量,其中一些是包含多个值的 Sass 映射。所有这些变量及其值都用于构建 Bootstrap 5 的不同元素,并且它们都可以进行自定义。
我们不会看到如何自定义 Bootstrap 5 所有元素(无论是布局、内容、表单、组件、辅助工具还是实用工具)的示例,但我们将从每个类别中通过足够的示例来学习如何更改其他所有内容。
查找变量名的一种替代方法
您还可以通过查看 scss 文件夹根目录下的部分文件来找到 Bootstrap 5 各个元素的变量名。例如,如果您进入 _breadcrumb.scss 文件,您可以看到该组件在不同 CSS 声明中使用的变量。在那里,您可以查看变量作为值被用于哪个属性,但通常,只需在 _variables.scss 文件中查找变量就足够简单、快捷且足够了。
带有 !default 标志的默认值
所有 Bootstrap 5 变量都使用!default标志。这个标志的功能在上一章的默认值子节中进行了描述。简而言之,!default标志用于在导入 Bootstrap 5 Sass 文件之前预先设置变量值。这就是 Bootstrap 5 定制工作的方式。
空值默认变量
在 886 个变量中,有 44 个具有null值。当这些变量在 Bootstrap 5 源代码的其他地方用作 CSS 声明时,该声明将无法编译。这是一种为用户提供更多定制选项的智能方式,而不会因为不必要的样式而膨胀代码库。如果用户选择在导入 Bootstrap 5 文件之前定义这些变量中的一个的值,那么null !default的值将被覆盖,CSS 声明将可以编译。
以第591行的$headings-font-style变量为例,它有一个null !default的默认值。这个变量在_reboot.scss文件中被用于一些标题的一般样式,如下所示:
font-style: $headings-font-style;
当值为null时,这个 CSS 声明将无法编译。然而,如果我们给变量赋一个值,声明将可以编译。这样,标题将不会有任何特定的字体样式,但由于$headings-font-style变量已经可供开发者使用,因此可以很容易地赋予它们一个样式。
摘要
你现在已经学会了如何从官方网站或 NPM 下载 Bootstrap 5 源代码。你也了解了scss文件夹及其子文件夹中的 Bootstrap 5 Sass 文件和变量,以及这些文件和变量是如何相互关联的。最后,你学习了如何导入和编译 Bootstrap 5。
在下一章中,我们将开始通过关注全局选项和调色板来定制 Bootstrap 5 样式。
第四章:第四章:Bootstrap 5 全局选项和颜色
在本章中,我们将开始自定义 Bootstrap 5。在介绍一些关于代码示例的重要信息之后,我们将学习如何更改全局选项,然后如何自定义颜色。
更改全局选项和自定义颜色将对 Bootstrap 5 的许多元素产生影响,因此了解这类自定义很有用,因为它们可以为您节省大量时间。
在本章中,我们将讨论以下主题:
-
单独导入 Bootstrap 5 文件
-
更改全局选项
-
自定义颜色
技术要求
-
为了预览示例,您需要一个代码编辑器和浏览器。
-
您还需要一个 Sass 编译器来编译 Sass 文件到 CSS。请参阅第二章,使用和编译 Sass,了解不同的方法。
您可以在 GitHub 上找到本章的代码文件,链接为github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide。
关于代码示例
在本章中,我将提供从 Bootstrap 5 Sass 文件中摘取的代码示例。我将包括文件名和行号,这样您就可以更容易地找到特定的代码。
我对 Bootstrap 5 的代码进行了以下修改,以便您更好地了解:
-
原始 Bootstrap 5 源代码中的注释已被省略
-
在某些情况下,删除了变量名和其值之间的多余空格,但并非全部,以适应本书的布局并保持大多数内容在一行内
保留了空行,这样在 Bootstrap 5 源代码中更容易找到代码示例。
单独导入 Bootstrap 5 文件
在上一章中,我们看到了如何导入默认的 Bootstrap 5。当更改全局选项或覆盖任何默认变量(且不需要任何函数)时,这种方式导入 Bootstrap 5 是足够的。然而,为了有更细粒度的控制并能够以更高级的方式自定义 Bootstrap 5,我们需要单独导入 Bootstrap 5 的部分(其中一些需要按正确的顺序),并在 Bootstrap 5 部分之间适当的位置添加我们的自定义代码。
以下是单个 Bootstrap 5 部分的完整列表,以及放置我们自己的自定义代码的注释如下:
style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
// Default variable overrides
// Required
@import "../../../../../bootstrap/scss/variables";
// Variable value using existing variable
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
@import "../../../../../bootstrap/scss/containers";
@import "../../../../../bootstrap/scss/grid";
@import "../../../../../bootstrap/scss/tables";
@import "../../../../../bootstrap/scss/forms";
@import "../../../../../bootstrap/scss/buttons";
@import "../../../../../bootstrap/scss/transitions";
@import "../../../../../bootstrap/scss/dropdown";
@import "../../../../../bootstrap/scss/button-group";
@import "../../../../../bootstrap/scss/nav";
@import "../../../../../bootstrap/scss/navbar";
@import "../../../../../bootstrap/scss/card";
@import "../../../../../bootstrap/scss/accordion";
@import "../../../../../bootstrap/scss/breadcrumb";
@import "../../../../../bootstrap/scss/pagination";
@import "../../../../../bootstrap/scss/badge";
@import "../../../../../bootstrap/scss/alert";
@import "../../../../../bootstrap/scss/progress";
@import "../../../../../bootstrap/scss/list-group";
@import "../../../../../bootstrap/scss/close";
@import "../../../../../bootstrap/scss/toasts";
@import "../../../../../bootstrap/scss/modal";
@import "../../../../../bootstrap/scss/tooltip";
@import "../../../../../bootstrap/scss/popover";
@import "../../../../../bootstrap/scss/carousel";
@import "../../../../../bootstrap/scss/spinners";
@import "../../../../../bootstrap/scss/offcanvas";
@import "../../../../../bootstrap/scss/placeholders";
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
实用 API 和自定义样式
当我们想要使用实用 API 并包含我们自己的自定义样式时,前面的列表将略有扩展。我们将在第六章**,理解和使用 Bootstrap 5 实用 API,以及第八章**,使用 Bootstrap 5 变量、实用 API 和 Sass 自定义网站中分别看到如何做到这一点。
在那些需要我们单独导入 Bootstrap 5 部分的自定义示例中,我已经减少了在 // Optional Bootstrap CSS 注释下分组的长列表 Bootstrap 5 导入。这样做是为了使代码示例不会占用太多空间。以下是缩短后的列表:
style.scss
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
在本书的后面部分,我们还将看到如何通过仅包含我们需要的精确 Bootstrap 5 Sass 部分文件来优化我们的 CSS 代码。
现在我们已经了解了这些代码示例的更改,我们将开始自定义 Bootstrap 5。
修改全局选项
Bootstrap 5 提供了一套变量,用于启用或禁用样式和行为的不同全局选项。这些变量中的大多数可以在 _variables.scss 文件中找到,位于第 337 行至 352 行,除了 $spacer 变量,它位于第 374 行。
这里概述了不同可用的选项。它们按在 _variables.scss 文件中出现的顺序列出:
-
光标
-
圆角(border-radius)
-
阴影(box-shadow)
-
渐变
-
过渡效果
-
减速运动
-
平滑滚动
-
网格类
-
容器类
-
CSS 网格
-
按钮指针
-
响应式字体大小(RFS)
-
验证图标
-
负边距
-
废弃信息
-
重要工具
-
空格
我们现在将逐一介绍每个选项,并查看它们的变量名、默认值、定义位置、外观或功能,以及如何更改它们。对于每个选项,part-1/chapter-4/options/ 文件夹中都会有代码示例,每个示例的 Sass 文件内容将在以下部分展示。
光标
$enable-caret
true
_variables.scss,第 337 行
此选项使下拉组件的切换按钮上的伪元素中放置的光标启用。
这里你可以看到启用或禁用此选项将呈现的样子:

图 4.1 – 启用光标选项的下拉按钮(默认)

图 4.2 – 禁用光标选项的下拉按钮(已更改)
要禁用光标选项,请使用以下 Sass 代码:
part-1/chapter-4/options/caret/scss/style.scss
$enable-caret: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
圆角
$enable-rounded
true
_variables.scss,第 338 行
此选项在各个组件上启用预定义的边框半径样式。
这里你可以看到启用或禁用此选项将呈现的几个不同示例:

图 4.3 – 启用圆角选项的按钮(默认)

图 4.4 – 禁用圆角选项的按钮(已更改)

图 4.5 – 启用圆角选项的文本输入(默认)

图 4.6 – 禁用圆角选项的文本输入(已更改)

图 4.7 – 启用圆角选项的警报组件(默认)

图 4.8 – 禁用圆角选项的警报组件(已更改)
要禁用圆角选项,请使用以下 Sass 代码:
part-1/chapter-4/options/rounded/scss/style.scss
$enable-rounded: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
阴影
$enable-shadows
false
_variables.scss,行 339
此选项在各个组件上启用预定义的装饰性 box-shadow 样式。
这里你可以看到启用或禁用此选项将呈现的几个不同示例:

图 4.9 – 禁用阴影选项的图像缩略图(默认)

图 4.10 – 启用阴影选项的图像缩略图(已更改)

图 4.11 – 禁用阴影选项的 Select 组件(默认)

图 4.12 – 启用阴影选项的 Select 组件(已更改)

图 4.13 – 禁用阴影选项的进度组件(默认)

图 4.14 – 启用阴影选项的进度组件(已更改)
要启用阴影选项,请使用以下 Sass 代码:
part-1/chapter-4/options/shadows/scss/style.scss
$enable-shadows: true;
@import "../../../../../bootstrap/scss/bootstrap.scss";
渐变
$enable-gradients
false
_variables.scss,行 340
此选项通过背景图像样式在各个组件上启用预定义的渐变。这种视觉效果非常微妙,可能难以看到。然而,以下 CSS 将被用于大多数兼容组件,以在背景颜色之上创建渐变效果:
background-image: linear-gradient(180deg,
rgba(255,255,255,0.15), rgba(255,255,255,0));
在 carousel 组件上,将使用以下 CSS 代替:
.carousel-control-prev {
background-image: linear-gradient(90deg,
rgba(0,0,0,0.25), rgba(0,0,0,0.001));
}
.carousel-control-next {
background-image: linear-gradient(270deg,
rgba(0,0,0,0.25), rgba(0,0,0,0.001));
}
这里你可以看到启用或禁用此选项将呈现的几个不同示例:

图 4.15 – 禁用渐变选项的警报组件(默认)

图 4.16 – 启用渐变选项的警报组件(已更改)

图 4.17 – 禁用渐变选项的按钮(默认)

图 4.18 – 启用渐变选项的按钮(已更改)

图 4.19 – 禁用渐变选项的轮播组件(默认)

图 4.20 – 启用渐变选项的轮播组件(已更改)
要启用渐变选项,请使用以下 Sass 代码:
part-1/chapter-4/options/gradients/scss/style.scss
$enable-gradients: true;
@import "../../../../../bootstrap/scss/bootstrap.scss";
过渡
$enable-transitions
true
_variables.scss,第 341 行
此选项在各个组件上启用预定义的过渡效果。
在印刷品中无法展示示例,但过渡效果应用于手风琴、轮播图、模态框、进度条、浮动标签等。
要禁用过渡选项,请使用以下 Sass 代码:
part-1/chapter-4/options/transitions/scss/style.scss
$enable-transitions: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
减少运动
$enable-reduced-motion
true
_variables.scss,第 342 行
此选项启用 prefers-reduced-motion 媒体查询,根据用户的偏好移除或更改某些动画和过渡效果。
此选项适用于进度条和旋转器组件,要看到效果,您需要在计算机上更改一些设置。
要禁用减少运动选项,请使用以下 Sass 代码:
part-1/chapter-4/options/reduced-motion/scss/style.scss
$enable-reduced-motion: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
平滑滚动
$enable-smooth-scroll
true
_variables.scss,第 343 行
此选项全局启用平滑滚动行为,但不会影响偏好减少运动的用户。
要禁用平滑滚动选项,请使用以下 Sass 代码:
part-1/chapter-4/options/smooth-scroll/scss/style.scss
$enable-smooth-scroll: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
网格类
$enable-grid-classes
true
_variables.scss,第 344 行
此选项启用用于网格系统的 CSS 类的生成。这包括 .row、.col 和其他相关类。
要禁用网格类选项,请使用以下 Sass 代码:
part-1/chapter-4/options/grid-classes/scss/style.scss
$enable-grid-classes: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
容器类
$enable-container-classes
true
_variables.scss,第 345 行
此选项启用用于布局容器的 CSS 类的生成。这包括 .container、.container-fluid 和其他相关类。
要禁用容器类选项,请使用以下 Sass 代码:
part-1/chapter-4/options/container-classes/scss/style.scss
$enable-container-classes: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
CSS 网格
$enable-cssgrid
false
_variables.scss,第 346 行
此选项用于启用基于 CSS 网格的独立网格系统。
如果您想启用此功能,您应该使用前面提到的网格类选项禁用默认网格系统。
要启用 CSS 网格选项,请使用以下 Sass 代码:
part-1/chapter-4/options/css-grid/scss/style.scss
$enable-grid-classes: false;
$enable-cssgrid: true;
@import "../../../../../bootstrap/scss/bootstrap.scss";
按钮指针
$enable-button-pointers
true
_variables.scss 行 347
此选项为非禁用按钮元素和按钮组件(具有 .btn 类)添加指针光标。
在这里,您可以查看启用或禁用此选项将呈现的样子:

图 4.21 – 启用按钮指针选项的按钮(默认)

图 4.22 – 禁用按钮指针选项的按钮(已更改)
要禁用按钮指针选项,请使用以下 Sass 代码:
part-1/chapter-4/options/button-pointers/scss/style.scss
$enable-button-pointers: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
响应式字体大小
$enable-rfs
true
_variables.scss 行 348
此选项全局启用 RFS。您将在第十章“使用 Bootstrap 5 与高级 Sass 和 CSS 功能”中了解更多关于 RFS 以及如何使用它的信息。
要禁用 RFS 选项,请使用以下 Sass 代码:
part-1/chapter-4/options/responsive-font-sizes/scss/style.scss
$enable-rfs: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
验证图标
$enable-validation-icons
true
_variables.scss 行 349
此选项启用文本输入和某些自定义表单中的背景图像图标以用于验证状态。
在这里,您可以查看启用或禁用此选项将呈现的样子:

图 4.23 – 启用验证图标选项的默认有效文本输入

图 4.24 – 禁用验证图标选项的默认有效文本输入(已更改)

图 4.25 – 启用验证图标选项的默认无效文本输入

图 4.26 – 禁用验证图标选项的无效文本输入(已更改)
要禁用验证图标选项,请使用以下 Sass 代码:
part-1/chapter-4/options/validation-icons/scss/style.scss
$enable-validation-icons: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
负边距
$enable-negative-margins
false
_variables.scss 行 350
此选项启用生成负边距实用工具。
要启用负边距选项,请使用以下 Sass 代码:
part-1/chapter-4/options/negative-margins/scss/style.scss
$enable-negative-margins: true;
@import "../../../../../bootstrap/scss/bootstrap.scss";
弃用消息
$enable-deprecation-messages
true
_variables.scss 行 351
此选项启用 Sass 警告消息以显示已弃用的混入或函数。目前没有混入或函数被弃用,因此使用 Bootstrap 5 的此版本时,您不会遇到此警告消息。
要禁用弃用消息选项,请使用以下 Sass 代码:
part-1/chapter-4/options/deprecation-messages/scss/style.scss
$enable-deprecation-messages: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
此选项的代码示例有一个没有内容的 HTML 文件,因为此选项将只显示 Sass 警告消息,针对任何未来的已弃用混合或函数。
重要实用工具
$enable-important-utilities
true
_variables.scss,第 352 行
此选项启用实用类中的 !important 后缀。因此,此选项控制实用类 CSS 声明的值是否会在末尾添加 !important 并从而覆盖元素的所有先前样式。
以下是一个示例,展示了差异:
// Important utilities enabled
.text-center {
text-align: text-center !important;
}
// Important utilities disabled
.text-center {
text-align: text-center;
}
要禁用重要实用工具选项,请使用以下 Sass 代码:
part-1/chapter-4/options/important-utilities/scss/style.scss
$enable-important-utilities: false;
@import "../../../../../bootstrap/scss/bootstrap.scss";
间距
$spacer
1rem
_variables.scss,第 374 行
此变量指定了 _variables.scss 文件中许多其他组件变量(以及一些其他地方)使用的默认间距值。它还用于程序化生成间距实用工具。
在这里,您可以查看将此变量更改为 2rem 的示例:

图 4.27 – 设置为 1rem(默认)的间距警报组件

图 4.28 – 设置为 2rem(已更改)的间距警报组件

图 4.29 – 设置为 1rem(默认)的间距卡组件

图 4.30 – 设置为 2rem(已更改)的间距卡组件

图 4.31 – 设置为 1rem(默认)的间距实用工具

图 4.32 – 设置为 2rem(已更改)的间距实用工具
要将此变量的值更改为 2rem,请使用以下 Sass 代码:
part-1/chapter-4/options/spacer/scss/style.scss
$spacer: 2rem;
@import "../../../../../bootstrap/scss/bootstrap.scss";
现在我们已经了解了如何更改 Bootstrap 5 的全局选项,我们将继续学习如何自定义颜色。
自定义颜色
Bootstrap 5 拥有一个高级颜色系统,为所有元素提供正确的样式。这个颜色系统基于颜色变量,可以通过不同的方式自定义以匹配您的品牌或设计。
在本节中,我们将介绍以下主题:
-
颜色变量的概述
-
生成颜色类
-
向主题颜色添加颜色
-
从主题颜色中移除颜色
颜色变量的概述
_variables.scss 文件中的第一个许多变量是颜色变量。它们可以在第 9-321 行找到。
颜色系统按以下方式排序和分组:
-
灰色
-
常规颜色
-
颜色的色调和阴影
-
主题颜色
在这些组中的每一个,首先将单个颜色分配给不同的变量,然后这些变量被分配到 Sass 映射的键中,将这些相关颜色分组在一起。Sass 映射用于轻松遍历颜色列表。您可以在 Sass 映射中添加、删除或修改值,这将反映在许多组件中。我们将在本节后面看到一些示例。
但首先,我们将回顾之前列出的不同颜色组,并了解更多关于它们的颜色值、变量和 Sass 映射。
灰色
首先,我们有九种灰色色调和阴影,加上白色和黑色。行号、变量名称和默认值如下:
bootstrap/scss/_variables.scss
9 $white: #fff !default;
10 $gray-100: #f8f9fa !default;
11 $gray-200: #e9ecef !default;
12 $gray-300: #dee2e6 !default;
13 $gray-400: #ced4da !default;
14 $gray-500: #adb5bd !default;
15 $gray-600: #6c757d !default;
16 $gray-700: #495057 !default;
17 $gray-800: #343a40 !default;
18 $gray-900: #212529 !default;
19 $black: #000 !default;
这些颜色值代表以下实际颜色:

图 4.33 – 灰色加白色和黑色
这些变量(不包括 $white 和 $black)随后被分组到 $grays Sass 映射中:
bootstrap/scss/_variables.scss
24 $grays: (
25 "100": $gray-100,
26 "200": $gray-200,
27 "300": $gray-300,
28 "400": $gray-400,
29 "500": $gray-500,
30 "600": $gray-600,
31 "700": $gray-700,
32 "800": $gray-800,
33 "900": $gray-900
34 ) !default;
常规颜色
然后,我们有 10 种不同的常规颜色。行号、变量名称和默认值如下:
bootstrap/scss/_variables.scss
39 $blue: #0d6efd !default;
40 $indigo: #6610f2 !default;
41 $purple: #6f42c1 !default;
42 $pink: #d63384 !default;
43 $red: #dc3545 !default;
44 $orange: #fd7e14 !default;
45 $yellow: #ffc107 !default;
46 $green: #198754 !default;
47 $teal: #20c997 !default;
48 $cyan: #0dcaf0 !default;
这些颜色值代表以下实际颜色:

图 4.34 – 常规颜色
然后,这 10 个常规颜色变量加上 $black、$white、$gray-600 和 $gray-800 被分组到 $colors Sass 映射中:
bootstrap/scss/_variables.scss
52 $colors: (
53 "blue": $blue,
54 "indigo": $indigo,
55 "purple": $purple,
56 "pink": $pink,
57 "red": $red,
58 "orange": $orange,
59 "yellow": $yellow,
60 "green": $green,
61 "teal": $teal,
62 "cyan": $cyan,
63 "black": $black,
64 "white": $white,
65 "gray": $gray-600,
66 "gray-dark": $gray-800
67 ) !default;
颜色色调和阴影
在常规颜色之后,我们有一个长列表的常规颜色色调和阴影的单独颜色变量,接着是一个 Sass 映射列表,将这些颜色分组在一起。
使用自定义颜色函数生成常规颜色的单独色调和阴影,以调色(变亮)或阴影(变暗)颜色(参见下一源代码)。Bootstrap 5 中内置的自定义颜色函数使用 Sass 的 mix() 颜色函数来创建所需的颜色。
例如,我们将查看蓝色色调和阴影。行号、变量名称和默认值如下:
bootstrap/scss/_variables.scss
79 $blue-100: tint-color($blue, 80%) !default;
80 $blue-200: tint-color($blue, 60%) !default;
81 $blue-300: tint-color($blue, 40%) !default;
82 $blue-400: tint-color($blue, 20%) !default;
83 $blue-500: $blue !default;
84 $blue-600: shade-color($blue, 20%) !default;
85 $blue-700: shade-color($blue, 40%) !default;
86 $blue-800: shade-color($blue, 60%) !default;
87 $blue-900: shade-color($blue, 80%) !default;
在前面的代码中,您可以看到中间值 $blue-500 被分配给 $blue 颜色。比这更亮的值被调色,比这更暗的值使用自定义颜色函数进行阴影处理。
此列表之后是其他颜色(靛蓝、紫色、粉红色、红色、橙色、黄色、绿色、蓝绿色和青色)的类似列表,从第 179 行开始,我们有这些颜色的 Sass 映射。在蓝色颜色的情况下,Sass 映射看起来如下:
bootstrap/scss/_variables.scss
179 $blues: (
180 "blue-100": $blue-100,
181 "blue-200": $blue-200,
182 "blue-300": $blue-300,
183 "blue-400": $blue-400,
184 "blue-500": $blue-500,
185 "blue-600": $blue-600,
186 "blue-700": $blue-700,
187 "blue-800": $blue-800,
188 "blue-900": $blue-900
189 ) !default;
主题颜色
最后,我们从灰色和常规颜色组中选择了颜色,现在它们被分配到八个不同的主题颜色变量中。这些通常也被称为上下文颜色。行号、变量名称和默认值如下:
bootstrap/scss/_variables.scss
301 $primary: $blue !default;
302 $secondary: $gray-600 !default;
303 $success: $green !default;
304 $info: $cyan !default;
305 $warning: $yellow !default;
306 $danger: $red !default;
307 $light: $gray-100 !default;
308 $dark: $gray-900 !default;
这些颜色值代表以下实际颜色:

图 4.35 – 主题颜色
这些颜色随后被分组到 $theme-colors Sass 映射中:
bootstrap/scss/_variables.scss
312 $theme-colors: (
313 "primary": $primary,
314 "secondary": $secondary,
315 "success": $success,
316 "info": $info,
317 "warning": $warning,
318 "danger": $danger,
319 "light": $light,
320 "dark": $dark
321 ) !default;
注意到 $theme-colors Sass 映射包含特定的主题颜色变量。没有更多,也没有更少。$grays Sass 映射没有包含 $white 和 $black 颜色变量,而 $colors Sass 映射也包括了 $black、$white、$gray-600 和 $gray-800 颜色变量。这只是为了告诉您这种差异存在。
我们现在完成了所有可用颜色变量和 Sass 映射的概述。现在让我们看看如何将这些用于不同的目的。
生成颜色类
如果需要,您可以使用内置的 @each 规则轻松生成更多颜色类。然后,您可以遍历 Sass 映射中的键/值对,并定义要使用的类前缀。
这是遍历 Sass 映射的 @each 规则的语法:
@each $key, $value in $map {
.class-prefix-#{$key} {
css-property: $value;
}
}
如您所见,键被分配到 @each 表达式中的第一个变量名称,值被分配到第二个。然后使用 $key 与所选类前缀一起使用,而 $value 用于设置 CSS 属性的值。
我们现在将看到如何使用 @each 规则生成不同的颜色类组。
在导入所需文件后放置的自定义 Sass 代码
在大多数剩余的代码示例中,我们的自定义 Sass 代码放置在导入所需文件(包括 _variables.scss 文件)之后,并在导入可选的 Bootstrap 文件之前。当我们想要将现有变量作为另一个变量的值时,这是必要的,这种情况是我们想要根据现有的颜色变量生成颜色类。
灰色
从 $grays Sass 映射中生成背景颜色类,您需要使用以下 Sass 代码:
part-1/chapter-4/colors/grays/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Create background color classes from the "$grays" color map
@each $color, $value in $grays {
.bg-gray-#{$color} {
background-color: $value;
}
}
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
当您编译此代码时,您将得到常规的 Bootstrap CSS 以及以下背景颜色类:
part-1/chapter-4/colors/grays/css/style.css
.bg-gray-100 { background-color: #f8f9fa; }
.bg-gray-200 { background-color: #e9ecef; }
.bg-gray-300 { background-color: #dee2e6; }
.bg-gray-400 { background-color: #ced4da; }
.bg-gray-500 { background-color: #adb5bd; }
.bg-gray-600 { background-color: #6c757d; }
.bg-gray-700 { background-color: #495057; }
.bg-gray-800 { background-color: #343a40; }
.bg-gray-900 { background-color: #212529; }
此代码可以使用以下 HTML 进行测试:
part-1/chapter-4/colors/grays/index.xhtml
<div class="bg-gray-100">.bg-gray-100</div>
<div class="bg-gray-200">.bg-gray-200</div>
<div class="bg-gray-300">.bg-gray-300</div>
<div class="bg-gray-400">.bg-gray-400</div>
<div class="bg-gray-500">.bg-gray-500</div>
<div class="bg-gray-600">.bg-gray-600</div>
<div class="bg-gray-700">.bg-gray-700</div>
<div class="bg-gray-800">.bg-gray-800</div>
<div class="bg-gray-900">.bg-gray-900</div>
常规颜色
从 $colors Sass 映射中生成背景颜色类,您需要使用以下 Sass 代码:
part-1/chapter-4/colors/regular-colors/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Create background color classes from the "$grays" color map
@each $color, $value in $colors {
.bg-#{$color} {
background-color: $value;
}
}
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
当您编译此代码时,您将得到常规的 Bootstrap CSS 以及以下背景颜色类:
part-1/chapter-4/colors/regular-colors/css/style.css
.bg-blue { background-color: #0d6efd; }
.bg-indigo { background-color: #6610f2; }
.bg-purple { background-color: #6f42c1; }
.bg-pink { background-color: #d63384; }
.bg-red { background-color: #dc3545; }
.bg-orange { background-color: #fd7e14; }
.bg-yellow { background-color: #ffc107; }
.bg-green { background-color: #198754; }
.bg-teal { background-color: #20c997; }
.bg-cyan { background-color: #0dcaf0; }
.bg-dark { background-color: #000; }
.bg-white { background-color: #fff; }
.bg-gray { background-color: #6c757d; }
.bg-gray-dark { background-color: #343a40; }
此代码可以使用以下 HTML 进行测试:
part-1/chapter-4/colors/regular-colors/index.xhtml
<div class="bg-blue">.bg-blue</div>
<div class="bg-indigo">.bg-indigo</div>
<div class="bg-purple">.bg-purple</div>
<div class="bg-pink">.bg-pink</div>
<div class="bg-red">.bg-red</div>
<div class="bg-orange">.bg-orange</div>
<div class="bg-yellow">.bg-yellow</div>
<div class="bg-green">.bg-green</div>
<div class="bg-teal">.bg-teal</div>
<div class="bg-cyan">.bg-cyan</div>
<div class="bg-dark">.bg-dark</div>
<div class="bg-white">.bg-white</div>
<div class="bg-gray">.bg-gray</div>
<div class="bg-gray-dark">.bg-gray-dark</div>
蓝色的色调和阴影
要从 $blues Sass 映射生成背景颜色类,您需要使用以下 Sass 代码:
part-1/chapter-4/colors/tints-and-shades/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Create background color classes from the "$grays" color
// map
@each $color, $value in $blues {
.bg-#{$color} {
background-color: $value;
}
}
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
当您编译此代码时,您将得到常规的 Bootstrap CSS 以及以下背景颜色类:
part-1/chapter-4/colors/tints-and-shades/css/style.css
.bg-blue-100 { background-color: #cfe2ff; }
.bg-blue-200 { background-color: #9ec5fe; }
.bg-blue-300 { background-color: #6ea8fe; }
.bg-blue-400 { background-color: #3d8bfd; }
.bg-blue-500 { background-color: #0d6efd; }
.bg-blue-600 { background-color: #0a58ca; }
.bg-blue-700 { background-color: #084298; }
.bg-blue-800 { background-color: #052c65; }
.bg-blue-900 { background-color: #031633; }
以下 HTML 可以用于测试此代码:
part-1/chapter-4/colors/tints-and-shades/index.xhtml
<div class="bg-blue-100">.bg-blue-100</div>
<div class="bg-blue-200">.bg-blue-200</div>
<div class="bg-blue-300">.bg-blue-300</div>
<div class="bg-blue-400">.bg-blue-400</div>
<div class="bg-blue-500">.bg-blue-500</div>
<div class="bg-blue-600">.bg-blue-600</div>
<div class="bg-blue-700">.bg-blue-700</div>
<div class="bg-blue-800">.bg-blue-800</div>
<div class="bg-blue-900">.bg-blue-900</div>
混合颜色
您还可以创建一个新的自定义 Sass 映射,其中指定了混合颜色作为颜色变量或其他有效的颜色值,并使用以下 Sass 代码基于此生成颜色类:
part-1/chapter-4/colors/mixed-colors/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Create a new "$mixed-colors" map
$mixed-colors: (
"blue": $blue,
"green": green,
"red": #f00,
"primary": $primary
);
// Create color classes from the "$mixed-colors" map
@each $color, $value in $mixed-colors {
.bg-#{$color} {
background-color: $value;
}
}
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
当您编译此代码时,您将得到常规的 Bootstrap CSS 以及以下背景颜色类:
part-1/chapter-4/colors/mixed-colors/css/style.css
.bg-blue { background-color: #0d6efd; }
.bg-green { background-color: green; }
.bg-red { background-color: #f00; }
.bg-primary { background-color: #0d6efd; }
以下 HTML 可以用于测试此代码:
part-1/chapter-4/colors/mixed-colors/index.xhtml
<div class="bg-blue">.bg-blue</div>
<div class="bg-green">.bg-green</div>
<div class="bg-red">.bg-red</div>
<div class="bg-primary">.bg-primary</div>
向主题颜色添加颜色
Bootstrap 5 有八种主题颜色,这些颜色用于组件变化、辅助工具、实用工具等。您可以向 $theme-colors Sass 映射中添加更多颜色,该映射用于生成这些不同的变体。为此,我们首先创建一个新的 Sass 映射,其中包含新的键名和相应的值(可以是现有的颜色变量或任何其他有效的颜色值):
// Create your own color map
$custom-colors: (
"tertiary": $indigo,
"quaternary": $purple,
"quinary": $pink,
"senary": $orange,
"septenary": $teal
);
然后,我们将使用 Sass 中的 sass:map 模块的 map-merge() 函数将此 $custom-colors Sass 映射与现有的 $theme-colors Sass 映射合并。我们将要合并的两个映射作为参数传递,返回值将存储在 $theme-colors 变量中。这将覆盖默认的 $theme-colors 变量,该变量包含默认的主题颜色,从而增加我们可用的主题颜色列表。合并这两个映射的代码如下:
// Merge "$theme-colors" map and "$custom-colors" map
$theme-colors: map-merge($theme-colors, $custom-colors);
用于此场景的完整 Sass 代码如下:
part-1/chapter-4/colors/add-to-theme-colors/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Create your own color map
$custom-colors: (
"tertiary": $indigo,
"quaternary": $purple,
"quinary": $pink,
"senary": $orange,
"septenary": $teal
);
// Merge "$theme-colors" map and "$custom-colors" map
$theme-colors: map-merge($theme-colors, $custom-colors);
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
现在,我们将看到所有这些主题颜色看起来如何,以及一些新主题颜色在各个组件和实用工具中如何生效的示例:

图 4.36 – 所有颜色作为背景颜色实用工具显示

图 4.37 – 所有颜色作为文本颜色实用工具显示

图 4.38 – 带有新三级颜色的警告组件

图 4.39 – 带有新四级颜色的按钮组件

图 4.40 – 带有新五级颜色的列表组组件

图 4.41 – 带有新六进制颜色拉伸链接辅助类的实用类

图 4.42 – 带有新七进制颜色的边框实用类
本例的完整代码可以在 part-1/chapter-4/colors/add-to-theme-colors 文件夹中找到。
从主题颜色中移除颜色
要从主题颜色中移除颜色,我们可以使用 Sass 的 sass:map 模块中内置的 map-remove() 函数。作为此函数的参数,我们传入我们想要从中移除键/值对的映射,然后是我们要移除的键/值对的键。返回值将存储在 $theme-colors 变量中。这将然后覆盖默认的 $theme-colors 变量,该变量包含默认的主题颜色,因此,我们的可用主题颜色列表将减少。
从 $theme-colors 映射中移除主题颜色的代码如下:
part-1/chapter-4/colors/remove-from-theme-colors/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Remove from "$theme-colors" map
$theme-colors: map-remove($theme-colors, "info", "light",
"dark");
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
编译此代码后,我们将无法为任何组件变体、辅助类或工具使用 info、light 和 dark 颜色。
本例的完整代码可以在 part-1/chapter-4/colors/remove-from-theme-colors 文件夹中找到。
定义自定义颜色调色板
为了完成关于 Bootstrap 5 中颜色的这一部分,我们将学习如何定义一个自定义颜色调色板。这相当简单。首先,我们定义我们想要更改的主题颜色变量的自定义颜色值,然后我们导入 Bootstrap 5 所需的文件,最后,我们从 $theme-colors 映射中移除任何不需要的主题颜色。这样做很重要,因为我们首先想要定义自己的颜色值给颜色变量,然后想要修改位于 _variables.scss 文件中的 $theme-colors 映射。
在我们的例子中,我们想要更改 $primary、$success、$info、$warning 和 $danger 主题颜色变量的颜色值,并移除 $secondary 主题颜色。
必需的主题颜色键
一些主题颜色键是必需的,不能移除,否则会导致错误,因为它们被其他组件的 Sass 代码所使用。这包括 primary、success 和 danger 键。您可以替换这些键的值,但不能移除这些键本身。secondary 键不是必需的,因此可以移除而不会导致后续出现任何错误。
接下来,您将看到实现此目的所需的代码。请注意,我们必须在导入 Bootstrap 5 所需的文件之前指定主题颜色变量的自定义值:
part-1/chapter-4/colors/custom-color-palette/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
// Define color palette
$primary: #264653;
$success: #2A9D8F;
$info: #E9C46A;
$warning: #F4A261;
$danger: #E76F51;
// Required
@import "../../../../../bootstrap/scss/variables";
// Remove "secondary" from "$theme-colors" map
$theme-colors: map-remove($theme-colors, "secondary");
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
编译此代码后,Bootstrap 5 将现在使用以下颜色调色板:

图 4.43 – 我们自定义的颜色调色板以背景颜色实用工具的形式显示

图 4.44 – 我们自定义的颜色调色板以文本颜色实用工具的形式显示
本例的完整代码可以在part-1/chapter-4/colors/custom-color-palette文件夹中找到。
摘要
在本章中,我们学习了有关 Bootstrap 5 的全局选项以及如何更改它们。我们还学习了如何自定义 Bootstrap 5 的颜色,包括如何生成颜色类以及如何添加和移除用作主题颜色的颜色。
在下一章中,我们将学习如何自定义 Bootstrap 5 的各种元素。
第五章:第五章:自定义各种 Bootstrap 5 元素
在本章中,我们将学习如何自定义使用 Bootstrap 5 变量进行样式的所有 Bootstrap 元素的视觉样式。我们将了解影响您网站整体设计的布局和内容更改,以及影响特定元素且没有全局效果的更改。
当您想更改用户界面的细节时,了解如何更改网站的一般布局和内容以及如何自定义特定元素是有用的。
在本章中,我们将涵盖以下主题:
-
自定义布局
-
自定义内容
-
自定义表单
-
自定义组件
-
自定义辅助工具
-
自定义实用工具
技术要求
-
要预览示例,您需要一个代码编辑器和浏览器。
-
您需要一个 Sass 编译器来将 Sass 文件编译为 CSS。请参阅第二章,使用和编译 Sass,了解不同的实现方法。
您可以在 GitHub 上找到本章的代码文件,地址为 github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide
自定义布局
在这里,我们将学习如何自定义断点、容器和网格系统,以创建您所有内容所需的精确响应性和一般布局。
断点
断点定义了布局将更改并适应不同屏幕尺寸时的最小宽度。这些最小宽度用于媒体查询中。
断点、变量名和默认值的行号如下:
bootstrap/scss/_variables.scss
431 $grid-breakpoints: (
432 xs: 0,
433 sm: 576px,
434 md: 768px,
435 lg: 992px,
436 xl: 1200px,
437 xxl: 1400px
438 ) !default;
我们现在将使用以下 Sass 代码更改所有屏幕尺寸的最小宽度:
part-1/chapter-5/layout/breakpoints/scss/style.scss
// Specify the breakpoint sizes
$grid-breakpoints: (
xs: 0,
sm: 300px,
md: 600px,
lg: 900px,
xl: 1200px,
xxl: 1500px
);
@import "../../../../../bootstrap/scss/bootstrap.scss";
我们现在可以使用以下 HTML 创建一个简单的网格:
part-1/chapter-5/layout/breakpoints/index.xhtml
<div class="row">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-4
col-xxl-2">
<div class="bg-secondary text-white p-3">Column</div>
</div>
</div>
要查看更改断点后的效果,您应该在浏览器中打开示例并调整窗口大小。
容器
可以像我们看到的断点大小一样,以相同的方式定义不同屏幕尺寸的容器(.container)的最大宽度。这些最大宽度也用于媒体查询中。
容器最大宽度的行号、变量名和默认值如下:
bootstrap/scss/_variables.scss
450 $container-max-widths: (
451 sm: 540px,
452 md: 720px,
453 lg: 960px,
454 xl: 1140px,
455 xxl: 1320px,
456 ) !default;
注意,对于超小断点(xs),没有最大宽度。
我们现在将使用以下 Sass 代码更改所有屏幕尺寸的容器最大宽度:
part-1/chapter-5/layout/containers/scss/style.scss
// Specify the container maximum widths
$container-max-widths: (
sm: 300px,
md: 500px,
lg: 700px,
xl: 900px,
xxl: 1100px
);
@import "../../../../../bootstrap/scss/bootstrap.scss";
我们现在可以使用以下 HTML 创建一个简单的容器:
part-1/chapter-5/layout/containers/index.xhtml
<div class="container">
<div class="bg-secondary text-white p-3">Content</div>
</div>
要查看容器最大宽度更改的效果,您应该在浏览器中打开示例并调整窗口大小。
网格
网格的默认列数是 12,默认 gutters 宽度是 1.5rem。如果你想要网格中的不同列数或不同的 gutters 宽度,可以更改这些值。
容器最大宽度的行号、变量名称和默认值如下:
bootstrap/scss/_variables.scss
466 $grid-columns: 12 !default;
467 $grid-gutter-width: 1.5rem !default;
468 $grid-row-columns: 6 !default;
我们现在将使用以下 Sass 代码更改网格中的列数和默认的 gutters 宽度:
part-1/chapter-5/layout/grids/scss/style.scss
// Specify the number of grid columns and the gutter width
$grid-columns: 16;
$grid-gutter-width: 1rem;
@import "../../../../../bootstrap/scss/bootstrap.scss";
我们现在可以使用以下 HTML 创建一个简单的网格系统:
index.xhtml
<div class="row">
<div class="col-16 col-md-8 col-lg-4">
<div class="bg-secondary text-white p-3">Content</div>
</div>
<div class="col-16 col-md-8 col-lg-4">
<div class="bg-secondary text-white p-3">Content</div>
</div>
<div class="col-8 col-lg-4">
<div class="bg-secondary text-white p-3">Content</div>
</div>
<div class="col-8 col-lg-4">
<div class="bg-secondary text-white p-3">Content</div>
</div>
</div>
要查看更改列数和 gutters 宽度对网格的影响,你应该在浏览器中打开示例。
现在我们将学习如何自定义我们网站的各种内容。
自定义内容
内容的样式(排版、图片、表格和图形)可以使用在 _variables.scss 文件中找到的变量进行自定义,这些变量位于行 543–651 和行 1500–1513。
现在我们将看到如何自定义不同类型的内容。
排版
Bootstrap 5 中用于定义整体排版的变量有很多。实际上,有超过 50 个不同的变量。在大多数情况下,变量名称是自解释的,所以让我们深入了解并查看完整的列表。以下为排版元素的行号、变量名称和默认值:
bootstrap/scss/_variables.scss
543 $font-family-sans-serif: system-ui, -apple-system,
"Segoe UI", Roboto, "Helvetica Neue", Arial,
"Noto Sans", "Liberation Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji" !default;
544 $font-family-monospace: SFMono-Regular, Menlo, Monaco,
Consolas, "Liberation Mono", "Courier New", monospace
!default;
545
546 $font-family-base: var(--#{$variable-prefix}
font-sans-serif) !default;
547 $font-family-code: var(--#{$variable-prefix}
font-monospace) !default;
548
549
550
551 $font-size-root: null !default;
552 $font-size-base: 1rem !default;
553 $font-size-sm: $font-size-base * .875 !default;
554 $font-size-lg: $font-size-base * 1.25 !default;
555
556 $font-weight-lighter: lighter !default;
557 $font-weight-light: 300 !default;
558 $font-weight-normal: 400 !default;
559 $font-weight-semibold: 600 !default;
560 $font-weight-bold: 700 !default;
561 $font-weight-bolder: bolder !default;
562
563 $font-weight-base: $font-weight-normal !default;
564
565 $line-height-base: 1.5 !default;
566 $line-height-sm: 1.25 !default;
567 $line-height-lg: 2 !default;
568
569 $h1-font-size: $font-size-base * 2.5 !default;
570 $h2-font-size: $font-size-base * 2 !default;
571 $h3-font-size: $font-size-base * 1.75 !default;
572 $h4-font-size: $font-size-base * 1.5 !default;
573 $h5-font-size: $font-size-base * 1.25 !default;
574 $h6-font-size: $font-size-base !default;
575
576
577
578 $font-sizes: (
579 1: $h1-font-size,
580 2: $h2-font-size,
581 3: $h3-font-size,
582 4: $h4-font-size,
583 5: $h5-font-size,
584 6: $h6-font-size
585 ) !default;
586
587
588
589 $headings-margin-bottom: $spacer * .5 !default;
590 $headings-font-family: null !default;
591 $headings-font-style: null !default;
592 $headings-font-weight: 500 !default;
593 $headings-line-height: 1.2 !default;
594 $headings-color: null !default;
595
596
597
598 $display-font-sizes: (
599 1: 5rem,
600 2: 4.5rem,
601 3: 4rem,
602 4: 3.5rem,
603 5: 3rem,
604 6: 2.5rem
605 ) !default;
606
607 $display-font-family: null !default;
608 $display-font-style: null !default;
609 $display-font-weight: 300 !default;
610 $display-line-height: $headings-line-height !default;
611
612
613
614 $lead-font-size: $font-size-base * 1.25 !default;
615 $lead-font-weight: 300 !default;
616
617 $small-font-size: .875em !default;
618
619 $sub-sup-font-size: .75em !default;
620
621 $text-muted: $gray-600 !default;
622
623 $initialism-font-size: $small-font-size !default;
624
625 $blockquote-margin-y: $spacer !default;
626 $blockquote-font-size: $font-size-base * 1.25 !default;
627 $blockquote-footer-color: $gray-600 !default;
628 $blockquote-footer-font-size: $small-font-size !default;
629
630 $hr-margin-y: $spacer !default;
631 $hr-color: inherit !default;
632
633
634 $hr-bg-color: null !default;
635 $hr-height: $border-width !default;
636
637
638 $hr-border-color: null !default;
639 $hr-border-width: $border-width !default;
640 $hr-opacity: .25 !default;
641
642 $legend-margin-bottom: .5rem !default;
643 $legend-font-size: 1.5rem !default;
644 $legend-font-weight: null !default;
645
646 $dt-font-weight: $font-weight-bold !default;
647
648 $list-inline-padding: .5rem !default;
649
650 $mark-padding: .2em !default;
651 $mark-bg: $yellow-100 !default;
现在我们将看到一个示例,展示我们如何更改文本颜色、背景颜色、字体家族、字体大小、行高以及链接的全局样式,以及常规标题、显示标题和引导段落的更具体样式。
这里是包含这些排版元素的 HTML 代码:
part-1/chapter-5/content/typography/index.xhtml
<h2 class="text-muted my-3">Headings</h2>
<h1><h1> heading</h1>
<h2><h2> heading</h2>
<h3><h3> heading</h3>
<h4><h4> heading</h4>
<h5><h5> heading</h5>
<h6><h6> heading</h6>
<h2 class="text-muted my-3">Display headings</h2>
<h1 class="display-1">Display heading 1</h1>
<h1 class="display-2">Display heading 2</h1>
<h1 class="display-3">Display heading 3</h1>
<h1 class="display-4">Display heading 4</h1>
<h1 class="display-5">Display heading 5</h1>
<h1 class="display-6">Display heading 6</h1>
<h2 class="text-muted my-3">Lead paragraph</h2>
<p class="lead">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. In laoreet pellentesque
lorem sed elementum. Suspendisse maximus convallis ex.
<a href="#">Etiam eleifend velit leo</a>.
</p>
<h2 class="text-muted my-3">Paragraph</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
In laoreet pellentesque lorem sed elementum. Suspendisse
maximus convallis ex. <a href="#">Etiam eleifend velit
leo</a>.
</p>
使用默认的 Bootstrap 5 样式时,它看起来是这样的:

Figure 5.1 – Typographic elements with default Bootstrap 5 styles
要更改文本颜色和背景色的全局样式,我们将使用两个额外的变量。排版元素的行号、变量名称和默认值如下:
bootstrap/scss/_variables.scss
401 $body-bg: $white !default;
402 $body-color: $gray-900 !default;
要将字体家族从系统字体更改为自定义字体,我们将使用 Google Fonts。我们将在 Bootstrap 5 CSS 文件的 <link> 标签之后使用 <head> 标签:
part-1/chapter-5/content/typography/index.xhtml
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
更新我们的 HTML 文件后,我们现在需要使用以下 Sass 代码定义几个不同的排版变量:
part-1/chapter-5/content/typography/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Body styles
$body-bg: $gray-100;
$body-color: $gray-700;
// Basic typography styles
$font-family-base: 'Roboto', sans-serif;
$font-size-base: 1.5rem;
$line-height-base: 1.3;
$line-height-sm: 1;
// Link styles
$link-color: $info;
$link-decoration: none;
$link-hover-color: shift-color($link-color,
$link-shade-percentage);
$link-hover-decoration: underline;
// Heading styles
$h1-font-size: $font-size-base * 3.5;
$h2-font-size: $font-size-base * 3;
$h3-font-size: $font-size-base * 2.5;
$h4-font-size: $font-size-base * 2;
$h5-font-size: $font-size-base * 1.5;
$h6-font-size: $font-size-base;
$headings-font-weight: $font-weight-bold;
$headings-line-height: $line-height-sm;
$headings-margin-bottom: $spacer;
// Display styles
$display-font-sizes: (
1: $h1-font-size * 1.5,
2: $h2-font-size * 1.5,
3: $h3-font-size * 1.5,
4: $h4-font-size * 1.5,
5: $h5-font-size * 1.5,
6: $h6-font-size * 1.5
);
$display-font-weight: $font-weight-light;
$display-line-height: $headings-line-height;
// Lead styles
$lead-font-size: $font-size-base * 1.25;
$lead-font-weight: $font-weight-light;
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
编译 Sass 代码后,排版元素将看起来像这样:

Figure 5.2 – Typographic elements after applying the customizations
图片
您无法单独自定义图像的外观或行为。但您可以自定义图像缩略图的外观,这将在图像周围添加一些样式,但不会更改图像本身。默认图像缩略图的样子如下:

图 5.3 – 默认图像缩略图
我们现在将更改填充、背景颜色、边框颜色和边框半径。图像缩略图的这些属性的行号、变量名和默认值如下:
bootstrap/scss/_variables.scss
1500: $thumbnail-padding: .25rem;
1501: $thumbnail-bg: $body-bg;
1503: $thumbnail-border-color: $gray-300;
1504: $thumbnail-border-radius: $border-radius;
我们将使用以下 Sass 代码来更改这些变量:
part-1/chapter-5/content/images/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Specify variables
$thumbnail-padding: .5rem;
$thumbnail-bg: $gray-200;
$thumbnail-border-color: $gray-500;
$thumbnail-border-radius: 0;
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
我们现在可以使用以下 HTML 创建一个简单的图像缩略图:
part-1/chapter-5/content/images/index.xhtml
<img src="img/100x100.png" alt="Image thumbnail"
class="img-thumbnail">
编译 Sass 代码后,图像缩略图将看起来像这样:

图 5.4 – 填充、背景颜色、边框颜色和边框半径已更改的图像缩略图
图像
默认图像的样子如下:

图 5.5 – 默认图像
我们现在将更改图像标题的字体大小和颜色。图像的这些属性的行号、变量名和默认值如下:
bootstrap/scss/_variables.scss
1512 $figure-caption-font-size: $small-font-size;
1513 $figure-caption-color: $gray-600;
我们将使用以下 Sass 代码来更改这些变量:
part-1/chapter-5/content/figures/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Specify variables
$figure-caption-font-size: $font-size-lg;
$figure-caption-color: $body-color;
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
我们现在可以使用以下 HTML 创建一个简单的图像:
part-1/chapter-5/content/figures/index.xhtml
<figure class="figure">
<img src="img/600x400.png" class="figure-img img-fluid"
alt="Figure image">
<figcaption class="figure-caption">
Caption for the figure.</figcaption>
</figure>
编译 Sass 代码后,图像将看起来像这样:

图 5.6 – 图像标题字体大小和颜色已更改的图像
现在我们已经学习了如何自定义各种内容,我们将继续学习如何自定义表单。
自定义表单
可以使用位于 _variables.scss 文件的第 796 行至 1034 行和第 1313 行至 1318 行的表单变量来自定义表单元素。使用这些变量,您可以更改表单文本、表单标签、常规输入、复选框和单选按钮、开关、输入组、选择元素、范围输入、文件输入、浮动标签以及表单验证。
例如,我们将自定义一个范围输入。
范围
首先,让我们看看默认范围输入的样子:

图 5.7 – 默认范围输入
我们现在将更改范围输入的轨道高度、滑块宽度以及滑块边框半径。范围输入的这三个属性的行号、变量名和默认值如下:
bootstrap/scss/_variables.scss
972 $form-range-track-height: .5rem;
978 $form-range-thumb-width: 1rem;
982 $form-range-thumb-border-radius: 1rem;
我们将通过将这些值加倍使范围输入变为原来的两倍大。为此,请使用以下 Sass 代码:
part-1/chapter-5/forms/range/scss/style.scss
// Specify variables
$form-range-track-height: 1rem;
$form-range-thumb-width: 2rem;
$form-range-thumb-border-radius: 2rem;
@import "bootstrap/scss/bootstrap";
我们现在可以使用以下 HTML 创建一个简单的范围输入:
part-1/chapter-5/forms/range/index.xhtml
<input type="range" class="form-range">
编译 Sass 代码后,范围输入将呈现如下:

图 5.8 – 范围输入,已更改轨道高度、滑块宽度和滑块边框半径
现在我们已经看到了如何自定义表单元素的示例,我们将继续介绍如何自定义组件。
自定义组件
Bootstrap 5 的各种组件可以使用在 _variables.scss 文件中找到的变量进行自定义。每个组件的变量都分组在一起,但组不是按字母顺序排列的。我建议您直接搜索组件名称以找到相关变量的组,或参考以下列表:
-
折叠面板:第 1258-1288 行
-
警报:第 1439-1448 行
-
徽章:第 1379-1384 行
-
面包屑:第 1520-1530 行
-
按钮和按钮组:第 747-789 行
-
卡片:第 1236-1252 行
-
轮播图:第 1536-1566 行
-
关闭按钮:第 1588-1599 行
-
折叠:此组件没有变量或 CSS 代码,只有 JavaScript
-
下拉菜单:第 1132-1179 行
-
列表组:第 1470-1493 行
-
模态框:第 1391-1430 行
-
导航和标签页:第 1059-1078 行
-
导航栏:第 1085-1123 行
-
Offcanvas:第 1606-1618 行
-
分页:第 1186-1222 行
-
占位符:第 1229-1230 行
-
弹出框:第 1325-1351 行
-
进度条:第 1455-1463 行
-
Scrollspy:此组件没有变量或 CSS 代码,只有 JavaScript
-
滚动条:第 1573-1581 行
-
Toasts:第 1358-1372 行
-
工具提示:第 1294-1307 行
我们现在将看到如何自定义这些组件的一些。
面包屑
下面是一个默认面包屑组件的示例:

图 5.9 – 默认面包屑组件
此组件由 11 个不同的变量辅助构建。以下是这些变量的行号、变量名和默认值:
bootstrap/scss/_variables.scss
1520 $breadcrumb-font-size: null !default;
1521 $breadcrumb-padding-y: 0 !default;
1522 $breadcrumb-padding-x: 0 !default;
1523 $breadcrumb-item-padding-x: .5rem !default;
1524 $breadcrumb-margin-bottom: 1rem !default;
1525 $breadcrumb-bg: null !default;
1526 $breadcrumb-divider-color: $gray-600 !default;
1527 $breadcrumb-active-color: $gray-600 !default;
1528 $breadcrumb-divider: quote("/") !default;
1529 $breadcrumb-divider-flipped:
$breadcrumb-divider !default;
1530 $breadcrumb-border-radius: null !default;
我们现在将更改面包屑分隔符号使用的符号从斜杠符号(/)更改为大于符号(>)。我们将使用以下 Sass 代码更改面包屑分隔符号:
part-1/chapter-5/components/breadcrumbs/scss/style.scss
// Specify variables
$breadcrumb-divider: quote(">");
@import "../../../../../bootstrap/scss/bootstrap.scss";
我们现在可以使用以下 HTML 创建一个面包屑组件:
part-1/chapter-5/components/breadcrumbs/index.xhtml
<nav aria-label="Breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item"><a href="#">Sports</a></li>
<li class="breadcrumb-item"><a href="#">Ball games</a>
</li>
<li class="breadcrumb-item active"
aria-current="page">Baseball</li>
</ol>
</nav>
编译 Sass 代码后,面包屑组件将呈现如下:

图 5.10 – 已更改分隔符号的面包屑组件
卡片
下面是一个卡片组件网格的示例:

图 5.11 – 卡片组件的默认网格
卡片组件是通过 17 个不同的变量组合而成的。以下是一些变量的行号、变量名和默认值:
bootstrap/scss/_variables.scss
1236 $card-spacer-y: $spacer !default;
1237 $card-spacer-x: $spacer !default;
1238 $card-title-spacer-y: $spacer * .5 !default;
1239 $card-border-width: $border-width !default;
1240 $card-border-color: rgba($black, .125) !default;
1241 $card-border-radius: $border-radius !default;
1242 $card-box-shadow: null !default;
1243 $card-inner-border-radius: subtract(
$card-border-radius, $card-border-width) !default;
1244 $card-cap-padding-y: $card-spacer-y * .5 !default;
1245 $card-cap-padding-x: $card-spacer-x !default;
1246 $card-cap-bg: rgba($black, .03) !default;
1247 $card-cap-color: null !default;
1248 $card-height: null !default;
1249 $card-color: null !default;
1250 $card-bg: $white !default;
1251 $card-img-overlay-padding: $spacer !default;
1252 $card-group-margin: $grid-gutter-width * .5 !default;
默认情况下,卡片的高度将基于其内部的内容。我们可以通过以下 Sass 代码更改卡片高度,使网格中的卡片默认具有相同的高度:
part-1/chapter-5/components/cards/scss/style.scss
$card-height: 100%;
@import "../../../../../bootstrap/scss/bootstrap.scss";
现在,我们可以使用以下 HTML 创建一个卡片组件的网格:
part-1/chapter-5/components/cards/index.xhtml
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-3
row-cols-xxl-4 g-4 mb-4">
<div class="col">
<div class="card">
<img class="card-img-top" src="img/300x150.png"
alt="Card image">
<div class="card-body">
<h4 class="card-title">Card title</h4>
<p class="card-text">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Maecenas feugiat,
urna ut pharetra ultricies, augue tellus euismod
turpis, vitae semper ipsum augue a velit.
Pellentesque id finibus velit. Ut sagittis
maximus maximus. In aliquet enim sed turpis
mollis ornare. Suspendisse elementum a magna eu
luctus. Etiam tincidunt mattis mauris, non
lobortis nulla tempor in. Sed lacinia metus
viverra, scelerisque enim sed, sollicitudin
magna. Sed non augue sit amet nisl tincidunt
ultrices. Praesent nec lacus eget tortor
ultricies pulvinar. Praesent euismod ut lorem sit
amet bibendum.</p>
</div>
<div class="card-footer">Created DD-MM-YYYY</div>
</div>
</div>
<!-- Three more card components with different text
content placed here -->
</div>
编译 Sass 代码后,卡片组件的网格现在将看起来像这样:

图 5.12 – 卡片高度更改后的卡片组件网格
我们现在已经看到了如何自定义组件,接下来是关于如何自定义辅助工具的部分。
自定义辅助工具
唯一可以通过 _variables.scss 文件中找到的变量来自定义的辅助工具是比率辅助工具。它有一个默认值的 Sass 映射,可以根据你的喜好进行修改。其他一些辅助工具使用主题颜色、其他元素的变量,或者只有非视觉方面可以自定义。这就是为什么我们在这里专注于比率辅助工具。
在这个例子中,我们将向之前提到的映射中添加更多的宽高比,然后这些宽高比将作为额外的辅助类可用。以下是一些宽高比映射的行号、变量名和默认值:
bootstrap/scss/_variables.scss
528 $aspect-ratios: (
529 "1x1": 100%,
530 "4x3": calc(3 / 4 * 100%),
531 "16x9": calc(9 / 16 * 100%),
532 "21x9": calc(9 / 21 * 100%)
533 ) !default;
我们现在将首先创建自己的 Sass 比率映射,并使用这些新值将其与现有的 $aspect-ratios 映射合并。你将在下一章学习更多关于 Sass 映射的工作方式。
要进行这些更改,我们需要编写以下 Sass 代码:
part-1/chapter-5/helpers/ratio/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Create your own ratio map
$custom-ratios: (
"1x2": calc(1 / 2 * 100%),
"2x3": calc(2 / 3 * 100%),
"3x4": calc(3 / 4 * 100%),
"4x5": calc(4 / 5 * 100%)
);
// Merge with "$aspect-ratios" map
$aspect-ratios: map-merge($aspect-ratios, $custom-ratios);
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
现在,我们可以使用以下 HTML 创建一个简单的示例,其中包含四个具有这些新不同宽高比的 <div> 元素:
part-1/chapter-5/helpers/ratio/index.xhtml
<div class="d-flex align-items-start">
<div class="ratio ratio-1x1">
<p class="d-flex justify-content-center
align-items-center border">1x1</p>
</div>
<div class="ratio ratio-4x3">
<p class="d-flex justify-content-center
align-items-center border">4x3</p>
</div>
<div class="ratio ratio-16x9">
<p class="d-flex justify-content-center
align-items-center border">16x9</p>
</div>
<div class="ratio ratio-21x9">
<p class="d-flex justify-content-center
align-items-center border">21x9</p>
</div>
</div>
编译 Sass 代码后,我们现在有 1x2、2x3、3x4 和 4x5 的宽高比可用,可以作为特定的辅助类使用。这些新的宽高比看起来像这样:

图 5.13 – 比率辅助类的新的宽高比值
我们现在已经看到了如何自定义比率辅助工具,在本章的最后部分,我们将看到如何自定义实用工具。
自定义实用工具
所有实用工具都是使用实用工具 API 生成的,其中大多数都在 _utilities.scss 文件中声明,除了背景、边框、颜色、位置、阴影和间距实用工具,这些实用工具在 _variables.scss 文件中有变量和映射定义。我们在上一章已经学习了如何自定义文本颜色和背景颜色,你可以在下一章了解实用工具 API。
现在,我们将查看一些使用 _variables.scss 文件中的值生成的工具。
边框
边框工具是从 _variables.scss 文件中找到的变量生成的,行号 480–500。我们将看到如何更改用于生成边框宽度工具的值。
边框宽度的值存储在一个 Sass 映射中,行号、变量名和默认值如下:
bootstrap/scss/_variables.scss
481 $border-widths: (
482 1: 1px,
483 2: 2px,
484 3: 3px,
485 4: 4px,
486 5: 5px
487 ) !default;
默认的边框宽度工具看起来是这样的:

图 5.14 – 边框宽度工具的默认尺寸
现在,我们将将五个边框宽度工具的大小加倍。要更改边框宽度工具的值,我们将自己指定 $border-widths Sass 映射,从而覆盖默认的 $border-widths Sass 映射及其值。为此,我们需要编写以下 Sass 代码:
part-1/chapter-5/utilities/borders/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Specify widths for border utility
$border-widths: (
1: 2px,
2: 4px,
3: 6px,
4: 8px,
5: 10px
);
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
我们现在可以用以下 HTML 创建一个简单的示例,包含五个 <div> 元素,这些元素使用这些新的更宽的边框宽度:
part-1/chapter-5/utilities/borders/index.xhtml
<div class="border border-1 mb-2">.border-1</div>
<div class="border border-2 mb-2">.border-2</div>
<div class="border border-3 mb-2">.border-3</div>
<div class="border border-4 mb-2">.border-4</div>
<div class="border border-5">.border-5</div>
编译 Sass 代码后,我们现在有了新的边框宽度,可以作为特定的边框宽度工具类使用。新的边框宽度工具看起来是这样的:

图 5.15 – 边框宽度工具的新尺寸
间距
间距工具是从 _variables.scss 文件中的一个单变量生成的。该变量存储一个 Sass 映射,该映射的值基于全局 $spacer 变量。我们将看到如何更改该 Sass 映射中的值,同时仍然使用 $spacer 变量。
行号、变量名和默认值如下:
bootstrap/scss/_variables.scss
375 $spacers: (
376 0: 0,
377 1: $spacer * .25,
378 2: $spacer * .5,
379 3: $spacer,
380 4: $spacer * 1.5,
381 5: $spacer * 3,
382 ) !default;
默认的填充间距工具看起来是这样的:

图 5.16 – 默认的填充间距工具
现在,我们将更改默认的间距值并添加两个新值。新的将获得一个字母作为其类名后缀,而不是数字:q 代表 $spacer 值的四分之一,h 代表 $spacer 值的一半。为此,我们将自己指定 $spacers Sass 映射,从而覆盖默认的 $spacers Sass 映射及其值。我们需要编写以下 Sass 代码:
part-1/chapter-5/utilities/spacing/scss/style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
// Specify spacer sizes
$spacers: (
0: 0,
q: $spacer / 4,
h: $spacer / 2,
1: $spacer,
2: $spacer * 2,
3: $spacer * 3,
4: $spacer * 4,
5: $spacer * 5
);
// Required
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../../bootstrap/scss/reboot";
@import "../../../../../bootstrap/scss/type";
@import "../../../../../bootstrap/scss/images";
// The long list of imports have been reduced here.
// Helpers
@import "../../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
编译 Sass 后,我们现在有了新的间距工具,可以作为特定的间距工具类使用。然后我们可以创建一个简单的示例,包含八个 <div> 元素,这些元素使用以下 HTML 表示这些更新的间距值:
part-1/chapter-5/utilities/spacing/index.xhtml
<div class="bg-secondary text-white p-0">p-0</div>
<div class="bg-secondary text-white p-q">p-q - "quarter"
(1/4) of p-1</div>
<div class="bg-secondary text-white p-h">p-h - "half" (1/2)
of p-1</div>
<div class="bg-secondary text-white p-1">p-1</div>
<div class="bg-secondary text-white p-2">p-2</div>
<div class="bg-secondary text-white p-3">p-3</div>
<div class="bg-secondary text-white p-4">p-4</div>
<div class="bg-secondary text-white p-5">p-5</div>
新的填充间距工具看起来是这样的:

图 5.17 – 用于填充的间距工具的变化
摘要
在本章中,我们学习了如何自定义 Bootstrap 5 的各个元素,包括布局、内容、表单、组件、辅助工具和实用工具。在下一章中,我们将学习有关实用 API 的所有内容。
第六章:第六章:理解和使用 Bootstrap 5 实用 API
在本章中,我们将学习如何使用 实用 API 生成和添加新的简单和复杂实用类,以及覆盖、修改和删除现有实用类。
当您需要调整组件或整体布局时,了解如何使用实用 API 是有用的,例如,控制元素的空间或尺寸、添加上下文颜色、更改边框或创建基于 flexbox 的布局。
在本章中,我们将涵盖以下主题:
-
关于实用 API
-
理解实用 API 语法
-
使用实用 API
对于最后两个部分,将有大量的代码示例来帮助理解强大的实用 API。
技术要求
-
要预览示例,您需要一个代码编辑器和浏览器。所有代码示例的源代码可以在以下位置找到:
github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide。 -
您需要一个 Sass 编译器来编译 Sass 文件到 CSS。请参阅 第二章,使用和编译 Sass,了解不同的方法。
关于实用 API
Bootstrap 5 特有的所谓实用 API,用于生成不同的实用类和/或 CSS 自定义属性(也称为 CSS 变量)。它的工作方式如下:
-
_utilities.scss文件包含$utilities变量,这是一个 Sass 映射,包含由实用 API 使用的各种设置。实际上,它是多个映射,通过使用map-merge()Sass 函数合并成一个包含嵌套映射的单个映射。共有 83 组实用类,它们按名称分组。它们的设置和值在每个组中都有所不同,但其中一些共享一些值(例如,一些弹性实用类共享flex类前缀)。 -
$utilities变量在utilities/_api.scss文件中使用,该文件在其他所有 Bootstrap 5 元素导入之后。 -
在
utilities/_api.scss文件中,$utilities变量作为参数传递给位于mixins/_utilities.scss文件的generate-utility()混合。 -
generate-utility()混合是 Bootstrap 5 在mixin子文件夹中找到的各种混合中最大和最先进的。当传递一个包含所需和可选值的 Sass 映射给它时,真正的魔法就发生了。
我们不会详细学习实用 API 中的 Sass 代码是如何工作的,而是将学习其语法,并查看不同示例,了解我们如何使用它来生成和添加简单和复杂的新实用类,以及覆盖、修改和删除现有实用类。
理解实用 API 语法
现在,让我们看看实用 API 的语法。首先是所有选项的语法概述,每行代码上方有一行注释。在注释中,你可以看到名称,在括号中,你可以看到选项是必需的还是可选的,在代码行中,你可以看到名称,后面跟着在方括号中接受的值的类型,以及(如果有)括号中的默认值:
$utilities: (
// Name (required)
"[String]": (
// Property (required)
property: [name],
// Values (required)
values: [space-separated list or map],
// Class (optional)
class: [name (null)],
// CSS variable utilities (optional)
css-var: [Boolean (false)],
// CSS variable name (optional)
css-variable-name: [name (null)],
// Local CSS variables (optional)
local-vars: [map (null)],
// State (optional)
state: [space-separated list (null)],
// Responsive (optional)
responsive: [Boolean (false)],
// RFS (optional)
rfs: [Boolean (false)],
// Print (optional),
print: [Boolean (false)],
// RTL,
rtl: [Boolean (true)]
)
);
我们将逐一介绍这些选项,并查看它们一起的作用,以下是一些示例。
关于代码示例
本章中所有代码示例的 Bootstrap 5 导入已减少,仅包括与实用 API 一起工作时所需的导入。对于本节中与实用 API 语法相关的示例,SCSS 文件顶部的必需导入如下:
style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
对于其他与使用实用 API 相关的示例,SCSS 文件顶部的必需导入如下:
style.scss
// Required
@import "../../../../../bootstrap/scss/functions";
@import "../../../../../bootstrap/scss/variables";
@import "../../../../../bootstrap/scss/maps";
@import "../../../../../bootstrap/scss/mixins";
@import "../../../../../bootstrap/scss/root";
@import "../../../../../bootstrap/scss/reboot";
在必需的导入之后,我们导入默认的实用工具,添加我们自己的自定义代码,最后导入实用工具 API。它看起来像这样:
style.scss
// Utilities
@import "../../../../../bootstrap/scss/utilities";
// Custom code here
// Utilities API
@import "../../../../../bootstrap/scss/utilities/api";
现在我们已经看到了本章 SCSS 文件的结构,我们可以省略仅导入 Bootstrap 5 部分的代码,专注于自定义代码。HTML 示例也已减少,仅显示必要的代码。记住,对于每个代码示例,都有指向包含所有导入的完整示例的文件引用。
名称
这是实用工具的名称,应该是一个带引号的字符串。它在生成的 CSS 中不被使用,所以它更多的是一种组织代码的方式:
$utilities: (
"Utility name": (
// Options defined here
)
);
CSS 属性
CSS 属性应该写成不带引号的,并且必须是一个有效的 CSS 属性。它可以是一个 CSS 属性(最常见)或一个由空格分隔的 CSS 属性列表。它用于 CSS 规则,如果未定义class键,它也是默认类名。
一个 CSS 属性
这里有一个包含一个 CSS 属性的示例:
part-1/chapter-6/api-syntax/css-property-single/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700
)
);
// Utilities API
这编译成以下内容:
part-1/chapter-6/api-syntax/css-property-single/css/style.css
.font-weight-300 { font-weight: 300 !important }
.font-weight-400 { font-weight: 400 !important }
.font-weight-700 { font-weight: 700 !important }
现在,我们可以通过以下 HTML 来查看这个实用工具的效果:
part-1/chapter-6/api-syntax/css-property-single/index.xhtml
<p class="font-weight-300">Lorem ipsum...</p>
<p class="font-weight-400">Lorem ipsum...</p>
<p class="font-weight-700">Lorem ipsum...</p>
要查看这个示例的实际效果,请在一个浏览器中打开 HTML 文件。
多个 CSS 属性
这里有一个包含多个 CSS 属性的示例:
part-1/chapter-6/api-syntax/css-property-multiple/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Spacing": (
property: margin padding,
values: $spacers,
class: spacing
)
);
// Utilities API
这编译成以下内容:
part-1/chapter-6/api-syntax/css-property-multiple/css/style.css
.spacing-0 {
margin: 0 !important;
padding: 0 !important
}
.spacing-1 {
margin: .25rem !important;
padding: .25rem !important
}
.spacing-2 {
margin: .5rem !important;
padding: .5rem !important
}
.spacing-3 {
margin: 1rem !important;
padding: 1rem !important
}
.spacing-4 {
margin: 1.5rem !important;
padding: 1.5rem !important
}
.spacing-5 {
margin: 3rem !important;
padding: 3rem !important
}
现在,我们可以通过以下 HTML 来查看这个实用工具的效果:
part-1/chapter-6/api-syntax/css-property-multiple/index.xhtml
<div style="margin: 1rem; padding: 1rem;"
class="spacing-0">.spacing-0</div>
<div class="spacing-1">.spacing-1</div>
<div class="spacing-2">.spacing-2</div>
<div class="spacing-3">.spacing-3</div>
<div class="spacing-4">.spacing-4</div>
<div class="spacing-5">.spacing-5</div>
要查看这个示例的实际效果,请在一个浏览器中打开 HTML 文件。
值
这指定了指定 CSS 属性的值,这些值在生成类名和 CSS 规则时使用。
它可以是一个空格分隔的值列表,用于类名和 CSS 规则:
values: 300 400 700
或者,如果您不想让类名与值相同,您可以使用映射:
values: (
light: 300,
normal: 400,
bold: 700
)
让我们再次使用第一个示例中的一个 CSS 属性,并将值从列表更改为映射:
part-1/chapter-6/api-syntax/values/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: (
light: 300,
normal: 400,
bold: 700
)
)
);
// Utilities API
这会编译成以下内容:
part-1/chapter-6/api-syntax/values/css/style.css
.font-weight-light { font-weight: 300 !important }
.font-weight-normal { font-weight: 400 !important }
.font-weight-bold { font-weight: 700 !important }
还可以引用存储列表或映射的 Sass 变量:
values: $font-weights
我们现在可以通过以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/values/index.xhtml
<p class="font-weight-light">Lorem ipsum...</p>
<p class="font-weight-normal">Lorem ipsum...</p>
<p class="font-weight-bold">Lorem ipsum...</p>
要查看此效果,请在一个浏览器中打开 HTML 文件。
类
此选项用于更改编译 CSS 中使用的 class 前缀。这是可选的,并且前缀应不带引号。考虑我们之前的第一个示例:
part-1/chapter-6/api-syntax/class/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700,
class: fw
)
);
// Utilities API
这会编译成以下内容:
part-1/chapter-6/api-syntax/class/css/style.css
.fw-300 { font-weight: 300 !important; }
.fw-400 { font-weight: 400 !important; }
.fw-700 { font-weight: 700 !important; }
我们现在可以通过以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/class/index.xhtml
<p class="fw-300">Lorem ipsum...</p>
<p class="fw-400">Lorem ipsum...</p>
<p class="fw-700">Lorem ipsum...p>
要查看此效果,请在一个浏览器中打开 HTML 文件。
CSS 变量实用工具
这是一个布尔选项,可以用来为选择器生成 CSS 变量而不是常规 CSS 规则。
让我们将第一个示例改为生成 CSS 变量而不是常规 CSS 规则:
part-1/chapter-6/api-syntax/css-variable-utilities/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700,
css-variable-name: fw,
css-var: true
)
);
// Utilities API
这会编译成以下内容:
part-1/chapter-6/api-syntax/css-variable-utilities/css/style.css
.font-weight-300 { --bs-fw: 300 }
.font-weight-400 { --bs-fw: 400 }
.font-weight-700 { --bs-fw: 700 }
我们现在可以通过以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/css-variable-utilities/index.xhtml
<p class="font-weight-300">Lorem ipsum...</p>
<p class="font-weight-400">Lorem ipsum...</p>
<p class="font-weight-700">Lorem ipsum...</p>
此 HTML 必须与以下 CSS 结合使用,该 CSS 位于我们示例中 HTML 文件的 <style> 标签中:
part-1/chapter-6/api-syntax/css-variable-utilities/index.xhtml
p[class^="font-weight"] { font-weight: var(--bs-fw); }
CSS 选择器针对页面上所有以 font-weight 开头的段落元素,然后使用存储在各个类名中的 --bs-fw 变量设置字体粗细。
要查看此效果,请在一个浏览器中打开 HTML 文件。
CSS 变量名称
此选项定义了在默认 --bs- 前缀之后生成的 CSS 变量实用工具的前缀,正如我们在上一个示例中所做的那样,与 css-var: true 一起使用,如下所示:css-variable-name: fw。完整的前缀,正如我们所见,变成了 --bs-fw。
本地 CSS 变量
使用此布尔选项,实用工具 API 仍然会生成 CSS 规则,但也会在这些规则内生成本地 CSS 变量。您必须指定一个 Sass 映射作为值,其中映射的键是 CSS 变量名称,映射的值是 CSS 变量值。
让我们将第一个示例也改为生成本地 CSS 变量:
part-1/chapter-6/api-syntax/local-css-variables/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700,
local-vars: (
font-weight-opacity: 0.5
)
)
);
// Utilities API
这会编译成以下内容:
part-1/chapter-6/api-syntax/local-css-variables/css/style.css
.font-weight-300 {
--bs-font-weight-opacity: .5;
font-weight: 300 !important
}
.font-weight-400 {
--bs-font-weight-opacity: .5;
font-weight: 400 !important
}
.font-weight-700 {
--bs-font-weight-opacity: .5;
font-weight: 700 !important
}
我们现在可以通过以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/local-css-variables/index.xhtml
<p class="font-weight-300">Lorem ipsum...</p>
<p class="font-weight-400">Lorem ipsum...</p>
<p class="font-weight-700">Lorem ipsum...</p>
此 HTML 必须与以下 CSS 结合使用,该 CSS 位于我们示例中 HTML 文件的 <style> 标签中:
part-1/chapter-6/api-syntax/local-css-variables/index.xhtml
p[class^="font-weight"] {
opacity: var(--bs-font-weight-opacity);
}
CSS 选择器针对页面上所有以 font-weight 开头的类段元素,然后使用存储与各种类名一起的 --bs-font-weight-opacity 变量设置字体粗细。
要看到这个功能的效果,请在浏览器中打开 HTML 文件。
状态
此选项用于在正常实用工具类之外生成伪类变体。您可以指定单个伪类或以空格分隔的伪类列表。当使用 state 选项时,实用工具 API 将为该伪类生成类名,并将伪类的名称附加到类名中。
让我们再次更改我们的第一个示例:
part-1/chapter-6/api-syntax/state/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700,
state: hover
)
);
// Utilities API
这将编译成以下内容:
part-1/chapter-6/api-syntax/state/css/style.css
.font-weight-300 { font-weight: 300 !important; }
.font-weight-300-hover:hover { font-weight: 300 !important; }
.font-weight-400 { font-weight: 400 !important; }
.font-weight-400-hover:hover { font-weight: 400 !important; }
.font-weight-700 { font-weight: 700 !important; }
.font-weight-700-hover:hover { font-weight: 700 !important; }
我们现在可以通过使用以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/state/index.xhtml
<p class="font-weight-300-hover">Lorem ipsum...</p>
<p class="font-weight-400-hover">Lorem ipsum...</p>
<p class="font-weight-700-hover">Lorem ipsum...</p>
要看到这个功能的效果,请在浏览器中打开 HTML 文件并将鼠标悬停在段落上。
响应式
此布尔选项用于在所有断点处生成响应式实用工具。它将设备缩写作为中缀插入到类名中。
让我们使我们的示例具有响应性:
part-1/chapter-6/api-syntax/responsive/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700,
responsive: true
)
);
// Utilities API
这将编译成以下内容:
part-1/chapter-6/api-syntax/responsive/css/style.css
.font-weight-300 { font-weight: 300 !important; }
.font-weight-400 { font-weight: 400 !important; }
.font-weight-700 { font-weight: 700 !important; }
@media (min-width: 576px) {
.font-weight-sm-300 { font-weight: 300 !important; }
.font-weight-sm-400 { font-weight: 400 !important; }
.font-weight-sm-700 { font-weight: 700 !important; }
}
@media (min-width: 768px) {
.font-weight-md-300 { font-weight: 300 !important; }
.font-weight-md-400 { font-weight: 400 !important; }
.font-weight-md-700 { font-weight: 700 !important; }
}
// and so on...
我们现在可以通过使用以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/responsive/index.xhtml
<h3>All breakpoints</h3>
<p class="font-weight-300">Lorem ipsum...</p>
<p class="font-weight-400">Lorem ipsum...</p>
<p class="font-weight-700">Lorem ipsum...</p>
<h3>Breakpoint sm</h3>
<p class="font-weight-sm-300">Lorem ipsum...</p>
<p class="font-weight-sm-400">Lorem ipsum...</p>
<p class="font-weight-sm-700">Lorem ipsum...</p>
// and so on...
要看到这个功能的效果,请在浏览器中打开 HTML 文件并调整浏览器窗口的大小。
RFS
此布尔选项将启用与 RFS Sass 插件一起的流体缩放。您将在第十章**,使用 Bootstrap 5 和高级 Sass 及 CSS 功能中了解更多关于此插件的信息。
打印
此布尔选项除了生成正常的实用工具类之外,还会为打印生成实用工具类。
让我们最后一次使用我们的示例:
part-1/chapter-6/api-syntax/print/scss/style.scss
// Required imports
// Utilities
$utilities: (
"Font weight": (
property: font-weight,
values: 300 400 700,
print: true
)
);
// Utilities API
这将编译成以下内容:
part-1/chapter-6/api-syntax/print/css/style.css
.font-weight-300 { font-weight: 300 !important; }
.font-weight-400 { font-weight: 400 !important; }
.font-weight-700 { font-weight: 700 !important; }
@media print {
.font-weight-print-300 { font-weight: 300 !important; }
.font-weight-print-400 { font-weight: 400 !important; }
.font-weight-print-700 { font-weight: 700 !important; }
}
我们现在可以通过使用以下 HTML 来看到这个实用工具的效果:
part-1/chapter-6/api-syntax/print/index.xhtml
<p class="font-weight-print-300 ">Lorem ipsum...</p>
<p class="font-weight-print-400 ">Lorem ipsum...</p>
<p class="font-weight-print-700 ">Lorem ipsum...</p>
要看到这个功能的效果,请在浏览器中打开 HTML 文件,然后在浏览器菜单中选择打印。这将打开一个打印对话框,您可以在其中预览应用了打印样式的页面。
RTL
此布尔选项指定实用工具是否应包含在编译样式的 RTL 版本中。这是 Bootstrap 5 的一个版本,它支持布局、组件和实用工具中的从右到左的文本。
!important
使用工具 API 生成的所有工具类都添加了!important,以确保它们覆盖组件和修饰类的设计。可以通过将$enable-important-utilities选项设置为false来禁用此功能,这在第四章中提到过,Bootstrap 5 全局选项和颜色。
更多语法示例
要查看更多工具 API 语法的例子,您可以查看 Bootstrap 5 中的_utilities.scss文件。在这里,您将看到用于生成 Bootstrap 5 中所有默认工具类的语法。
使用工具 API
我们已经看到了工具 API 的语法,现在我们将看到一些如何用于不同目的的例子。首先,我们将看到如何生成和添加简单和复杂的新工具的例子,然后我们将看到如何覆盖、修改和删除现有工具的例子。为此,我们将使用以下两个 Sass 函数:map-merge()(合并现有映射)和map-get()(从指定的 Sass 映射中获取与键关联的值)。
添加一个简单工具
首先,我们将生成并添加一个简单的光标工具,它可以用来在悬停于特定元素时更改光标。我们指定了工具的名称("cursor"),要使用的 CSS 属性(cursor),以及用于该 CSS 属性的值(auto context-menu copy grab help pointer wait)。这些是在使用工具 API 时必须指定的最小选项。
在使用工具 API 的语法之前,我们使用map-merge() Sass 函数将$utilities变量中的现有工具设置与这个新工具合并。这样做是为了避免覆盖$utilities变量并丢失所有默认工具。
代码看起来是这样的:
part-1/chapter-6/examples/add-simple-utility/scss/style.scss
// Required imports
// Utilities
// Generate simple cursor utilities
$utilities: map-merge(
$utilities,
(
"cursor": (
property: cursor,
values: auto context-menu copy grab help pointer wait
)
)
);
// Utilities API
这将编译所有默认工具,以及以下新工具:
part-1/chapter-6/examples/add-simple-utility/css/style.css
.cursor-auto { cursor: auto !important; }
.cursor-context-menu { cursor: context-menu !important; }
.cursor-copy { cursor: copy !important; }
.cursor-grab { cursor: grab !important; }
.cursor-help { cursor: help !important; }
.cursor-pointer { cursor: pointer !important; }
.cursor-wait{ cursor: wait !important; }
我们现在可以通过使用以下 HTML 来看到这些工具的效果:
part-1/chapter-6/examples/add-simple-utility/index.xhtml
<p class="cursor-auto">.cursor-auto</p>
<p class="cursor-context-menu">.cursor-context-menu</p>
<p class="cursor-copy">.cursor-copy</p>
<p class="cursor-grab">.cursor-grab</p>
<p class="cursor-help">.cursor-help</p>
<p class="cursor-pointer">.cursor-pointer</p>
<p class="cursor-wait">.cursor-wait</p>
要看到这个效果,请在一个浏览器中打开 HTML 文件,并用鼠标悬停在不同的元素上。
添加一个复杂工具
现在,这里有一个如何生成并添加一个具有许多选项的复杂不透明度工具的例子。我们指定了工具的名称("opacity"),要使用的 CSS 属性(opacity),用于该 CSS 属性的值(作为 Sass 映射,以便类名可以与 CSS 值不同),要使用的类前缀(o),以及使此工具在hover上工作的状态,并且我们启用了responsive和print选项。
再次,我们使用map-merge()函数将现有工具与这个新工具合并。
代码看起来是这样的:
part-1/chapter-6/examples/add-complex-utility/scss/style.scss
// Required imports
// Utilities
// Generate complex opacity utilities
$utilities: map-merge(
$utilities,
(
"opacity": (
property: opacity,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
),
class: o,
state: hover,
responsive: true,
print: true
)
)
);
// Utilities API
这将编译所有默认工具,以及以下新工具:
part-1/chapter-6/examples/add-complex-utility/css/style.css
.o-0 { opacity: 0 !important }
.o-0-hover:hover { opacity: 0 !important }
.o-25 { opacity: .25 !important }
.o-25-hover:hover { opacity: .25 !important }
.o-50 { opacity: .5 !important }
.o-50-hover:hover { opacity: .5 !important }
.o-75 { opacity: .75 !important }
.o-75-hover:hover { opacity: .75 !important }
.o-100 { opacity: 1 !important }
.o-100-hover:hover { opacity: 1 !important }
@media (min-width: 576px) {
.o-sm-0 { opacity: 0 !important }
.o-sm-0-hover:hover { opacity: 0 !important }
.o-sm-25 { opacity: .25 !important }
.o-sm-25-hover:hover { opacity: .25 !important }
.o-sm-50 { opacity: .5 !important }
.o-sm-50-hover:hover { opacity: .5 !important }
.o-sm-75 { opacity: .75 !important }
.o-sm-75-hover:hover { opacity: .75 !important }
.o-sm-100 { opacity: 1 !important }
.o-sm-100-hover:hover { opacity: 1 !important }
}
// and so on…
我们现在可以通过以下 HTML 来查看这些工具的效果:
part-1/chapter-6/examples/add-complex-utility/index.xhtml
<h3>All breakpoints</h3>
<p class="o-0">.o-0</p>
<p class="o-0-hover">.o-0-hover</p>
<p class="o-25">.o-25</p>
<p class="o-25-hover">.o-25-hover</p>
<p class="o-50">.o-50</p>
<p class="o-50-hover">.o-50-hover</p>
<p class="o-75">.o-75</p>
<p class="o-75-hover">.o-75-hover</p>
<p style="opacity: 0;" class="o-100">.o-100</p>
<p style="opacity: 0;" class="o-100-hover">.o-100-hover</p>
<h3>Breakpoint sm</h3>
<p class="o-sm-0">.o-sm-0</p>
<p class="o-sm-0-hover">.o-sm-0-hover</p>
<p class="o-sm-25">.o-sm-25</p>
<p class="o-sm-25-hover">.o-sm-25-hover</p>
<p class="o-sm-50">.o-sm-50</p>
<p class="o-sm-50-hover">.o-sm-50-hover</p>
<p class="o-sm-75">.o-sm-75</p>
<p class="o-sm-75-hover">.o-sm-75-hover</p>
<p style="opacity: 0;" class="o-sm-100">.o-sm-100</p>
<p style="opacity: 0;" class="o-sm-100-hover">
.o-sm-100-hover</p>
// and so on...
要查看此功能的效果,请在一个浏览器中打开 HTML 文件并将鼠标悬停在不同的元素上。
覆盖一个工具
您可以通过使用相同的名称来覆盖现有的工具。此方法也可以用来修改工具,但那时您必须小心,并使用所有相同的选项。
以下是一个如何使用具有更多指定值的新的"width"工具来覆盖尺寸工具的示例:
Part-1/chapter-6/examples/overwrite-utility/scss/style.scss
// Required imports
// Utilities
// Overwrite sizing utility for width
$utilities: map-merge(
$utilities,
(
"width": (
property: width,
class: w,
values: (
10: 10%,
20: 20%,
30: 30%,
40: 40%,
50: 50%,
60: 60%,
70: 70%,
80: 80%,
90: 90%,
100: 100%,
auto: auto
)
)
)
);
// Utilities API
这将编译所有默认工具,以及以下新工具:
part-1/chapter-6/examples/overwrite-utility/css/style.css
.w-10 { width: 10% !important }
.w-20 { width: 20% !important }
.w-30 { width: 30% !important }
.w-40 { width: 40% !important }
.w-50 { width: 50% !important }
.w-60 { width: 60% !important }
.w-70 { width: 70% !important }
.w-80 { width: 80% !important }
.w-90 { width: 90% !important }
.w-100 { width: 100% !important }
.w-auto { width: auto !important }
我们现在可以通过以下 HTML 来查看这些工具的效果:
part-1/chapter-6/examples/overwrite-utility/index.xhtml
<div class="w-10 bg-secondary text-white p-3 mb-2">.w-10
</div>
<div class="w-20 bg-secondary text-white p-3 mb-2">.w-20
</div>
<div class="w-30 bg-secondary text-white p-3 mb-2">.w-30
</div>
<div class="w-40 bg-secondary text-white p-3 mb-2">.w-40
</div>
<div class="w-50 bg-secondary text-white p-3 mb-2">.w-50
</div>
<div class="w-60 bg-secondary text-white p-3 mb-2">.w-60
</div>
<div class="w-70 bg-secondary text-white p-3 mb-2">.w-70
</div>
<div class="w-80 bg-secondary text-white p-3 mb-2">.w-80
</div>
<div class="w-90 bg-secondary text-white p-3 mb-2">.w-90
</div>
<div style="width: 50%;" class="w-100 bg-secondary
text-white p-3 mb-2">.w-100</div>
<div style="width: 50%;" class="w-auto bg-secondary
text-white p-3">.w-auto</div>
要查看此功能的效果,请在一个浏览器中打开 HTML 文件。
修改一个工具
可以修改现有的工具。在这个例子中,我们将"margin-start"工具的class前缀从.ms-*重命名为.ml-*。现在它将与 Bootstrap 4 中使用的相同前缀相同。这次,我们将使用map-get()函数从$utilities变量中获取"margin-start"属性的当前值,以便将其与class: ml属性合并,这将覆盖现有的class: ms属性。代码如下:
part-1/chapter-6/examples/modify-utility/scss/style.scss
// Required imports
// Utilities
// Rename class for existing utility
$utilities: map-merge(
$utilities, (
"margin-start": map-merge(
map-get($utilities, "margin-start"),
( class: ml ),
)
)
);
// Utilities API
这将编译所有默认工具,以及以下新工具:
part-1/chapter-6/examples/modify-utility/css/style.css
.ml-0 { margin-left: 0 !important }
.ml-1 { margin-left: .25rem !important }
.ml-2 { margin-left: .5rem !important }
.ml-3 { margin-left: 1rem !important }
.ml-4 { margin-left: 1.5rem !important }
.ml-5 { margin-left: 3rem !important }
.ml-auto { margin-left: auto !important }
我们现在可以通过以下 HTML 来查看这些工具的效果:
part-1/chapter-6/examples/modify-utility/index.xhtml
<div class="ml-1 bg-secondary text-white p-3 mb-2">.ml-1
</div>
<div class="ml-2 bg-secondary text-white p-3 mb-2">.ml-2
</div>
<div class="ml-3 bg-secondary text-white p-3 mb-2">.ml-3
</div>
<div class="ml-4 bg-secondary text-white p-3 mb-2">.ml-4
</div>
<div class="ml-5 bg-secondary text-white p-3 mb-2">.ml-5
</div>
要查看此功能的效果,请在一个浏览器中打开 HTML 文件。重命名的margin-left工具类现在可以正常工作。
删除一个工具
可以从现有的工具集中删除一个工具。在这里,您可以看到如何通过将它们的值设置为null来删除"user-select"和"pointer-events"交互工具:
part-1/chapter-6/examples/remove-utility/scss/style.scss
// Required imports
// Utilities
// Remove interaction utilities
$utilities: map-merge(
$utilities,
(
"user-select": null,
"pointer-events": null
)
);
// Utilities API
这将编译所有默认工具,除了"user-select"和"pointer-events"工具。
我们现在可以通过尝试以下 HTML 来查看这些工具确实已被删除:
part-1/chapter-6/examples/remove-utility/index.xhtml
<h3>User select</h3>
<h4>All</h4>
<p class="user-select-all">Lorem ipsum...</p>
<h4>Auto</h4>
<p style="user-select: none;" class="user-select-auto">
Lorem ipsum...</p>
<h4>None</h4>
<p class="user-select-none">Lorem ipsum...</p>
<h3>Pointer events</h3>
<h4>None</h4>
<p><a href="#" class="pe-none">Lorem ipsum dolor sit amet,
consectetur adipiscing elit</a>. In laoreet pellentesque
lorem sed elementum. Suspendisse maximus convallis ex.
Etiam eleifend velit leo.</p>
<h4>Auto</h4>
<p><a href="#" style="pointer-events: none;"
class="pe-auto">Lorem ipsum dolor sit amet, consectetur
adipiscing elit</a>. In laoreet pellentesque lorem sed
elementum. Suspendisse maximus convallis ex. Etiam
eleifend velit leo.</p>
<h4>None for parent, auto for second child</h4>
<p class="pe-none"><a href="#">Lorem ipsum dolor sit amet,
consectetur adipiscing elit</a>. In laoreet pellentesque
lorem sed elementum. Suspendisse maximus convallis ex.
<a href="#" class="pe-auto">Etiam eleifend velit leo</a>.
</p>
要查看此功能的效果,请在一个浏览器中打开 HTML 文件。对于"user-select"和"pointer-events"的工具不再起作用。
摘要
我们现在已经了解了关于实用 API 的所有内容,这是一个内置在 Bootstrap 5 中的非常强大的工具。这也是关于自定义 Bootstrap 5 的最后一章,同时也是本书第一部分的最后一章。在本书的下一部分,我们将看到如何在构建一个完整的网站并使用 Sass 和一些自定义 JavaScript 以多种不同的方式对其进行定制时,如何将这些知识付诸实践。
第二部分 – 基于 Bootstrap 5 和定制的独特外观网站创建
在本书的这一部分,我们将学习如何利用 Bootstrap 5 强大的定制功能,以及一些使用 Sass 的定制样式,将一个看起来标准的 Bootstrap 5 网站转变为一个独特且定制的网站。我们还将通过自定义 JavaScript 添加各种交互功能来提升网站。
本部分包括以下章节:
-
第七章,使用默认 Bootstrap 5 元素创建网站
-
第八章,使用 Bootstrap 5 变量、实用 API 和 Sass 定制网站
-
第九章,使用 JavaScript 交互功能提升网站
第七章:第七章: 使用默认 Bootstrap 5 元素创建网站
在本章中,我们将首先仔细看看我们将要创建的网站类型。然后,简要介绍 Bootstrap Icons,它在整个网站中被大量使用,以使其更加用户友好和视觉吸引人。之后,将描述页面设置,然后是几个在网站中使用的全局模块的截图描述,最后是每个页面类型的截图描述。
在本章中,我们将涵盖以下主要主题:
-
关于网站
-
Bootstrap Icons
-
页面设置
-
网站的全球模块
-
网站的页面类型
技术要求
要预览示例,你需要一个代码编辑器和浏览器。由于整个网站都是使用默认 Bootstrap 5 元素创建的,所以本章中代码示例不会很多。然而,完整网站的源代码可以在以下位置找到:
github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide.
关于网站
该网站是一个在线商店,包含产品概述、产品详情、想要清单、购物车和结账流程等与购物相关的页面,以及更多与信息相关的内容页面。它总共有 12 个页面,其中 8 个在结构和布局上独特,剩下的 4 个使用相同的结构和布局。
该网站仅使用默认 Bootstrap 5 元素进行设计和开发,内容包含占位文本和图片。因此,网站呈现出类似线框图的外观。然而,如果你替换所有文本和图片,网站将看起来更加真实。
您可能知道,Bootstrap 5 只包含网站前端的代码。因此,所有需要与后端通信的网站高级功能都没有实现。这包括搜索功能、筛选、排序、表单提交等。在第九章《使用 JavaScript 提高网站交互功能》中,我们将使用一些自定义 JavaScript 扩展基本功能,使网站更加交互和用户友好。
网站地图
下面是构成网站及其相互关系的页面概述。所有页面的描述将在本章后面进行:
-
首页
-
商店 => 产品
-
关于
-
联系方式
-
想要清单
-
购物车
-
常见问题解答
-
配送
-
退货
-
服务条款
-
隐私政策
如您所见,只有商店和产品页面具有父子关系。所有其他页面都位于顶级。
Bootstrap Icons
Bootstrap Icons 是由 Bootstrap 团队创建的免费、高质量的开源库。它可以与或没有 Bootstrap 一起使用,并且可以作为 SVG、SVG 精灵或网络字体使用。这个库的第一个 alpha 版本于 2019 年 11 月 26 日发布。最新版本,v1.8.3,于 2022 年 5 月 25 日发布,现在包含超过 1600 个图标可供选择。
Bootstrap Icons 可以在以下 URL 访问:icons.getbootstrap.com/。
从那里,你可以以不同的方式下载和安装它。我选择使用网络字体实现,这使得直接将图标添加到 HTML 代码中变得非常快速。要添加一个图标,你只需使用以下代码:
<i class="bi-[Icon name]"></i>
这里,[图标名称]指的是一个图标的名称,例如alarm,因此它变成了以下形式:
<i class="bi-alarm"></i>
这将在页面上显示以下图标:

图 7.1 – 警报图标
当使用图标作为网络字体时,颜色和大小可以像文本一样设置,例如,使用 Bootstrap 5 实用类。
在下一节中,你可以看到 Bootstrap Icons CSS 文件是如何在每页的<head>标签中链接的。
页面设置
大多数页面的基本设置如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>[Page title]</title>
<link rel="stylesheet" href="../../../
bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../../../
bootstrap-icons/font/bootstrap-icons.css">
</head>
<body>
<header>[Header]</header>
<div>[Page title]</div>
<div class="container">
<!-- Various sections -->
<section></section>
<section></section>
<section></section>
</div>
<footer>[Footer]</footer>
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
</html>
这是一个非常基础的 Bootstrap 5 实现。在<head>标签内,我们首先看到定义字符集的<meta>标签,然后是响应式元标签:
<meta name="viewport" content="width=device-width, initial-scale=1">
然后是<title>标签中的页面标题,以及指向压缩后的 Bootstrap 5 CSS 文件和 Bootstrap Icons CSS 文件的链接。
在<body>标签内,我们可以看到大多数页面的基本页面结构,首先是头部模块,然后是页面标题模块,.container内的各种部分,接着是页脚模块。最后,在关闭</body>标签之前,我们看到一个<script>标签,其中src指向的是捆绑和压缩后的 Bootstrap 5 JavaScript 文件。
全局模块
在我们浏览所有不同页面类型之前,我们将看到哪些全局模块被用于多个页面类型。
在接下来的描述中,任何正在使用的 Bootstrap 5 组件都会像这样突出显示:组件名称。术语模块指的是页面的一部分,与 Bootstrap 5 无关。
标题
这个全局模块用于所有页面类型。它位于每个页面的顶部,用于主要导航。它使用lg创建。
这里有三张模块的截图,分别显示在手机、平板和桌面设备上:

图 7.2 – 移动设备上的关闭菜单的头部模块

图 7.3 – 移动设备上的关闭菜单的头部模块

图 7.4 – 平板设备上的头部模块

图 7.5 – 桌面设备上的头部模块
模块的左侧包含两个元素。首先,品牌名称,然后是主菜单,包含链接到最重要的页面。活动页面将在菜单中突出显示。
模块的右侧包含三个元素。首先,一个创建为简单表单的搜索字段,使用 输入组 组件。它旨在用于网站所有内容和产品的全局搜索。然后,一个货币选择器来更改商店使用的货币。它使用 下拉 组件创建。最后,一个行动号召部分,包含两个分别用于心愿单和购物车的按钮样式链接。
页脚
此全局模块用于所有页面类型。它位于每个页面的底部,主要用于次要导航。它包含来自标题模块的所有链接,在 sm 断点下,以及 lg 断点下的四列网格。
在下面的图中,您将看到模块在移动、平板和桌面设备上的三个截图:

图 7.6 – 移动设备上的页脚模块

图 7.7 – 平板设备上的页脚模块

图 7.8 – 桌面设备上的页脚模块
前三个列包含一个标题,后面跟着一个未加样式的无序列表链接,在第三列,链接文本前面有一个图标。最后一列包含一个 <address> 元素内的基本联系信息。在这个模块的底部中央是一个居中的版权声明。
页面标题
此全局模块用于所有页面类型,除了主页和产品页。它位于标题模块之后,简单地显示在浅灰色背景上的居中标题。
该模块唯一的响应式行为是响应式字体大小,这是 Bootstrap 5 的默认功能。
这里是模块在移动、平板和桌面设备上的三个截图:

图 7.9 – 移动设备上的页面标题模块

图 7.10 – 平板设备上的页面标题模块

图 7.11 – 桌面设备上的页面标题模块
我们现在已经看到了页面标题全局模块的外观,接下来,我们将查看产品卡片全局模块。
产品卡片
此全局模块在主页、商店页面、产品页面和愿望单页面上的响应式网格系统中使用。它是一个卡片组件,包含产品图片、徽章组件用于标签、产品名称、品牌名称、描述、库存状态、定价信息和行动号召按钮。
此模块的唯一响应式行为是响应式字体大小,这是 Bootstrap 5 的默认功能。
这里是移动设备上看到的模块截图:

图 7.12 – 移动设备上的产品卡片模块
在愿望单页面,添加到愿望单按钮被从愿望单移除按钮所替代。
页面类型
这里是所有不同页面类型的描述。共有九种不同的页面类型用于创建 12 个不同的页面。其中八个只使用了一次,最后一个,文章页面,使用了四次。
主页(index.xhtml)
这是在线商店的主页。在此页面上,用户可以看到英雄部分、了解优点、探索集合、查看热门产品和注册新闻通讯。
这里是桌面设备上看到的完整页面的截图:
.jpg)
.png)
图 7.13 – 桌面设备上的主页
此页面的<body>标签中的整体代码结构如下。不同的模块已被替换为[模块名称]并在之后进一步描述(除了之前章节中已描述的页眉和页脚):
part-2/chapter-7/website/index.xhtml
<body>
[Header]
[Hero]
<div class="container">
[Benefits]
[Collections]
[Popular products]
</div>
[Newsletter]
[Footer]
[Modal]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
英雄
此模块是对在线商店的简要介绍,它由一个图片、一个显示标题、一个引言段落和两个行动号召按钮组成。此布局中的元素最初是堆叠的,然后对于lg断点及以上变为两列网格。
优点
此模块由一个图片、一个标题和一个段落组成。布局是通过使用响应式嵌套网格创建的,其中所有内容最初都是堆叠的。在sm断点处,内部网格变为两列,而在lg断点处,外部网格变为两列。
集合
此模块使用轮播组件显示不同的集合,每个幻灯片都有一个链接、图片和标题。
热门产品
此模块以响应式三列网格显示三个产品。每个产品都是使用之前章节中描述的产品卡片模块创建的。
新闻通讯
此模块由标题、三列网格布局中的表单以及触发模态的复选框标签中的链接组成。
模态
此模块由一个模态组件组成,该组件可以从之前描述的新闻模块中的链接触发。模态的内容是关于新闻通讯的信息。
商店 (shop.xhtml)
这是网上商店的商店页面。在此页面上,用户可以看到带有筛选器和产品列表的侧边栏,这些产品以响应式网格布局列出。在此之上,我们有一个面包屑、一个用于更改排序的控制按钮,以及用于在网格布局和列表布局之间切换产品布局的按钮。然而,对于此网站,只创建了商店页面的网格布局。在产品概述下方,我们有分页以在包含产品的各个页面之间导航。
在小于 lg 的断点处,筛选器包含在一个由面包屑上方的按钮触发的 Offcanvas 模块中。
下面是桌面设备上看到的完整页面的截图:
.jpg)
.jpg)
图 7.14 – 桌面设备上的商店页面
此页面的 <body> 标签中的整体代码结构如下。不同的模块已被替换为 [模块名称],它们将在之后进一步描述(除了标题和页脚,它们在前一节中已描述):
part-2/chapter-7/website/shop.xhtml
<body>
[Header]
[Page title]
<div class="container">
[Offcanvas]
[Sorting and layout]
[Breadcrumb and search result]
<div class="row">
<div class="col-lg-4 col-xxl-3 d-none d-lg-block">
<aside class="sticky-top pt-lg-3 pb-lg-5">
[Filters]
</aside>
</div>
<div class="col-lg-8 col-xxl-9 pt-lg-3 mb-5">
[Products overview]
[Pagination]
</div>
</div>
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
Offcanvas
此模块是使用 lg 断点及以上创建的。
排序和布局
此模块用于对产品概述进行排序和更改布局。它使用 <select> 元素来更改排序和 lg。
面包屑和搜索结果
此模块具有左侧的面包屑导航和右侧的搜索结果。面包屑导航是使用 面包屑 组件创建的。
筛选器
此模块包含产品概述的各种筛选选项。所有筛选器都包含在 卡片 组件中,而单个筛选器是使用各种表单元素创建的,例如 开关、复选框和 输入组。
产品概述
此模块使用产品购物车模块显示产品的响应式网格。最初,所有列都是堆叠的,然后在 md 断点时变为两列网格,在 xxl 断点时变为三列网格。
分页
此模块使用 分页 组件让用户在多个搜索结果页面之间导航。
产品 (product.xhtml)
此页面显示了商店导航的面包屑、产品画廊、产品详情和描述,以及相关产品和评论。此页面未使用 Bootstrap 5 组件,除了 面包屑 组件和 徽章 组件。相反,使用了大量的实用类,以及各种排版、表单元素、图像缩略图和引用块。
下面是桌面设备上看到的完整页面的截图:
.jpg)
.jpg)
图 7.15 – 桌面设备上的产品页面
下一个可以看到此页面的<body>标签中的整体代码结构。不同的模块已被替换为[模块名称]并在之后进一步描述(除了在上一节中已描述的页眉和页脚):
part-2/chapter-7/website/product.xhtml
<body>
[Header]
<div class="container mt-3 mb-5">
<section class="border-bottom border-2 border-light
mb-4 pb-4">
[Breadcrumb]
<div class="row">
<div class="col-lg-6">
[Gallery]
</div>
<div class="col-lg-6">
[Details and description]
</div>
</div>
</section>
[Related products]
[Review]
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
面包屑
此模块包含一个用于导航商店的面包屑导航。它使用面包屑组件创建。
画廊
此模块包含一个使用<figure>元素结构化的带图注的大产品图像。下面是一个包含六个图像缩略图的三个列网格。
详细信息和描述
此模块包含有关产品的各种细节。它具有与产品卡片模块相同的内容,用于选择颜色和大小的不同类型的表单控件、长描述和两个行动号召按钮。
相关产品
此模块显示相关产品。它包含一个标题,后面跟着一个包含产品卡片模块的三列响应式网格。
评论
此模块显示了带有图像、姓名、日期、评分和评论本身的三个评论块。Bootstrap 5 的默认引用块元素通过在左上角添加 Bootstrap 图标引用图标并使用 11 个实用类(文本、浮动、间距和边框实用类)进行了增强。
关于(about.xhtml)
此页面展示了有关在线商店的各种信息,包括文本和图像。
这里是桌面设备上看到的完整页面的截图:
.jpg)
.jpg)
图 7.16 – 桌面设备上的关于页面
下一个可以看到此页面的<body>标签中的整体代码结构。不同的模块已被替换为[模块名称]并在之后进一步描述(除了在上一节中已描述的页眉和页脚):
part-2/chapter-7/website/about.xhtml
<body>
[Header]
[Page title]
<div class="container">
[Story]
[Office]
[Brands]
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
故事
此模块包含一个标题和关于在线商店故事的三个段落。
办公室
此模块包含一个两列响应式网格,用于显示办公室的图像。每个列都包含一个用<figure>包裹的图像和图注。
品牌
此模块显示一个响应式网格,其中包含在线商店中产品的品牌标志。初始布局是两列网格,在sm断点时变为三列网格,在lg断点时变为六列网格。
联系(contact.xhtml)
此页面展示了团队概述、地图上的位置和联系表单。
这里是桌面设备上看到的完整页面的截图:
.jpg)
.jpg)
图 7.17 – 桌面设备上的联系页面
下一个将展示此页面 <body> 标签中的整体代码结构。不同的模块已被替换为 [模块名称],之后将对其进行进一步描述(除了在上一节中已描述的 Header 和 Footer):
part-2/chapter-7/website/contact.xhtml
<body>
[Header]
[Page title]
<div class="container">
[Team]
[Location]
[Contact form]
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
团队
此模块包含一个标题、一个段落和一个响应式网格,展示团队成员的图片、社交媒体网络的链接、姓名和职位。最初,布局是一个两列网格,在 md 断点时变为三列网格,在 xl 断点时变为六列网格。
位置
此模块包含一个嵌入的 Google Maps 地图,位于 <iframe> 元素中。使用比例辅助工具来保持地图的宽高比为 21 比 9。
联系表单
此模块包含一个标题和联系表单。联系表单的布局是通过使用响应式嵌套网格创建的,其中一切最初都是堆叠的。在 md 断点时,内部网格变为两列,在 xl 断点时,外部网格变为两列。
愿望单(wishlist.xhtml)
此页面显示了用户添加到愿望单中的产品。在左侧的侧边栏中,用户可以更改愿望单、创建新愿望单或一次性将所有产品添加到购物车。在主要区域中,有一个响应式网格系统,其中包含产品卡片,展示了当前愿望单上的所有产品。
下面是桌面设备上看到的完整页面的截图:
.jpg)
.jpg)
图 7.18 – 桌面设备上的愿望单页面
下一个将展示此页面 <body> 标签中的整体代码结构。不同的模块已被替换为 [模块名称],之后将对其进行进一步描述(除了在上一节中已描述的 Header 和 Footer):
part-2/chapter-7/website/wishlist.xhtml
<body>
[Header]
[Page title]
<div class="container">
<div class="row">
<div class="col-lg-4 col-xxl-3 mb-3 mb-lg-0">
[Sidebar]
</div>
<div class="col-lg-8 col-xxl-9 pt-lg-3 mb-5">
[Products overview]
</div>
</div>
</div>
[Footer]
[Modal]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
侧边栏
侧边栏模块使用 Card 组件包裹 List group 组件,显示用户的愿望单和一个创建新愿望单的按钮。当点击该按钮时,一个即将描述的模态模块(modal module)将变得可见。在卡片下方,有一个主要按钮,可以一次性将所有产品添加到购物车。
产品概述
这是一个使用产品卡片模块创建的响应式网格系统,用于显示当前愿望单上的产品。用户可以将产品添加到购物车,但“添加到愿望单”操作已被“从愿望单中移除”按钮所取代。
模态
当用户在侧边栏中点击创建新愿望单的按钮时,会触发一个 Modal 组件。此模态包含一个模态标题、一个关闭按钮、一个段落和一个简单的表单,带有输入组。
购物车(cart.xhtml)
此页面最初显示购物车,并将结账流程隐藏在标签页后面。在导航标签上方,还有一个进度条来显示结账流程的当前进度。
第一个标签页显示购物车,左侧是一个产品列表,右侧是一个总结,显示总金额。
第二个面板显示运输详情,包括个人详情表单、选择运输方式的按钮和一个信息警报。在右侧,有一个扩展的总结,包括产品列表和总金额。
第三个面板显示支付选项,左侧有一个信用卡详情表单和一个 PayPal 选项,右侧有一个扩展的总结,包括产品列表和总金额。
这里是桌面设备上整个页面的三个截图,每次显示一个标签页:

图 7.19 – 桌面设备上的购物车页面(标签 1 可见)

图 7.20 – 桌面设备上的购物车页面(标签 2 可见)

图 7.21 – 桌面设备上的购物车页面(标签 3 可见)
下一个可以看到此页面 <body> 标签中的整体代码结构。不同的模块已被替换为 [模块名称],之后将对其进行进一步描述(除了在上一节中已描述的标题和页脚):
part-2/chapter-7/website/cart.xhtml
<body>
[Header]
[Page title]
<div class="container">
[Progress bar]
[Tab navigation]
<div class="tab-content">
<div id="cartTabs-pane-1" class="tab-pane fade show
active" role="tabpanel" aria-labelledby=
"cartTabs-1">
<div class="row mb-5">
<div class="col-xl-8 mb-5 mb-xl-0">
[Shopping cart]
</div>
<div class="col-xl-4">
[Summary]
</div>
</div>
</div>
<div id="cartTabs-pane-2" class="tab-pane fade"
role="tabpanel" aria-labelledby="cartTabs-2">
<div class="row mb-5">
<div class="col-xl-8 mb-5 mb-xl-0">
[Shipping details]
</div>
<div class="col-xl-4">
[Summary]
</div>
</div>
</div>
<div id="cartTabs-pane-3" class="tab-pane fade"
role="tabpanel" aria-labelledby="cartTabs-3">
<div class="row mb-5">
<div class="col-xl-8 mb-5 mb-xl-0">
[Payment options]
</div>
<div class="col-xl-4">
[Summary]
</div>
</div>
</div>
</div>
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
进度条
此模块显示结账流程的当前进度。它使用 0 创建。当它从 1-100 的正数改变时,进度条将以主要颜色显示,并带有条纹和动画效果。
标签导航
此模块显示结账流程的三个步骤,每个标签页都有一个数字和标题。可以使用标签来更改可见的面板。该模块使用 .nav-pills 变体创建,将导航标签从标签更改为药丸形状。
购物车
此模块放置在第一个标签页的左侧,并显示购物车和产品列表。可以使用输入组组件更改每个产品的数量,也可以从购物车中删除产品。在最底部,用户可以进入下一个标签页或取消。
运输详情
此模块放置在第二个面板的左侧,并显示运输详情。首先,有一个使用响应式网格系统排列的个人详情表单,然后是一个按钮组组件,带有单选按钮,用于在两种不同的运输方式之间切换。下面有一个使用Alert组件创建的关于免费运输的信息警报。在最底部,用户可以进入下一个标签页或取消。
支付选项
此模块放置在第三个面板的左侧,显示支付选项。用户可以使用两个单选按钮在两种支付选项之间进行选择。首先,有一个信用卡详情表单,采用响应式网格系统布局,下面是 PayPal 选项。在最底部,用户可以选择支付或取消。
摘要
此模块在三个面板中都被使用。在第一个面板中,它只包含关于总金额的信息,而在第二个和第三个面板中,它还包含购物车中的产品列表。
常见问题(faq.xhtml)
本页面展示了三个部分,每个部分都有一个标题,后面跟着一个包含常见问题和答案的折叠面板。
下面是桌面设备上完整页面的截图:

图 7.22 – 桌面设备上的常见问题页面
下一个将展示此页面 <body> 标签中的整体代码结构。不同的模块已被替换为 [模块名称],之后将对其进行进一步描述(除了在上一节中已描述的页眉和页脚):
part-2/chapter-7/website/faq.xhtml
<body>
[Header]
[Page title]
<div class="container">
[Accordion]
[Accordion]
[Accordion]
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
折叠面板
此模块由一个标题和一个折叠面板组件组成。每个折叠面板项包含折叠面板标题中的常见问题及其在折叠面板主体中的相应答案。一次只能展开一个折叠面板项。
文章页面(shipping.xhtml、returns.xhtml、terms-of-service.xhtml 和 privacy-policy.xhtml)
本页面展示了以文章形式呈现的通用信息。它有一个固定在左侧的侧边栏,包含页面导航,以及包含各种排版元素、图片和表格的主区域。
下面是桌面设备上完整页面的截图:
.jpg)
.jpg)
图 7.23 – 桌面设备上的文章页面
下一个将展示此页面 <body> 标签中的整体代码结构。不同的模块已被替换为 [模块名称],之后将对其进行进一步描述(除了在上一节中已描述的页眉和页脚):
part-2/chapter-7/website/shipping.xhtml
part-2/chapter-7/website/returns.xhtml
part-2/chapter-7/website/terms-of-service.xhtml
part-2/chapter-7/website/privacy-policy.xhtml
<body>
[Header]
[Page title]
<div class="container">
<div class="row">
<div class="col-lg-3 mb-3 mb-lg-0">
[Page navigation]
</div>
<div class="col-lg-9 pt-lg-3">
[Article]
</div>
</div>
</div>
[Footer]
<script src="../../../bootstrap/dist/js/
bootstrap.bundle.min.js"></script>
</body>
页面导航
页面导航是通过一个卡片组件和一个内部的列表组组件创建的。它使用位置辅助工具使其固定。它还使用滚动侦听器组件来突出显示当前正在滚动的部分。
文章
文章包含各种排版元素:引言段落、不同的标题、常规段落、链接、无序列表、有序列表、图片和表格。
摘要
在本章中,我们首先简要介绍了为本书创建的网站项目,包括对网站地图的概述。然后,我们学习了如何使用 Bootstrap 图标使网站更具用户友好性和视觉吸引力。
本章的其余部分致力于概述正在使用的不同全局模块和页面类型,包括描述每个页面所使用的所有不同模块以及它们是如何仅使用默认的 Bootstrap 5 组件创建的。这还补充了在桌面设备上看到的所有页面的截图。
在下一章中,我们将使用 Sass 自定义我们网站的视觉风格。
第八章:第八章:使用 Bootstrap 5 变量、工具 API 和 Sass 定制网站
在本章中,我们将开始定制在前一章中描述和预览的网站。我们将主要通过更改一些用于样式化 Bootstrap 5 所有元素的 Bootstrap 5 变量来实现这一点。在这个过程中,我们将更改一些正在使用的网格和间距工具类,以更好地匹配新样式。我们还将使用工具 API 修改一些现有工具类,并通过使用这些新工具类来优化布局。最后,我们还将添加我们自己的 Sass 来进一步定制网站。
在本章中,将会有许多代码示例和一些截图,但我建议你在不同设备尺寸的浏览器中探索这个定制的网站版本,以真正看到与之前的不同。
在本章中,我们将介绍以下主要内容:
-
导入 Bootstrap 5 文件和自定义样式
-
默认变量覆盖
-
使用现有变量设置变量值
-
工具类
-
其他自定义样式
技术要求
-
预览示例需要代码编辑器和浏览器。所有代码示例的源代码都可以在这里找到:
github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide。 -
要将 Sass 编译为 CSS,你需要以下任何一个:
-
Node.js,如果你更喜欢使用终端(macOS)或命令提示符(Windows)的命令行界面(CLI)
-
Scout-App,如果你更喜欢使用图形用户界面(GUI)
-
Visual Studio Code,如果你更喜欢使用 Visual Studio Code 市场上的扩展
-
所有这些方法都在 第二章 使用和编译 Sass 中解释。
导入 Bootstrap 5 文件和自定义样式
在 第四章 Bootstrap 5 全局选项和颜色 中,我们学习了 bootstrap.scss 文件,以及它包含所有将导入 Bootstrap 5 各个元素单独 Sass 部分文件的代码。我们将使用这些 @import 语句的不同顺序,这将使定制更容易。我们还将添加四个我们自己的 SCSS 文件的 @import 语句,我们使用这些文件来覆盖变量(两个文件用于此目的)、定义工具类和添加自定义样式,在 Bootstrap 5 的 @import 语句之间。
@import 语句的顺序如下:
-
必须导入 Bootstrap 5 的
_functions.scss文件 -
导入我们自己的
_default-variable-overrides.scss文件,该文件用于默认变量覆盖 -
必须导入 Bootstrap 5 的
_variables.scss文件 -
导入我们自己的
_variable-value-using-variable.scss文件,该文件用于使用现有变量覆盖变量值 -
必须导入 Bootstrap 5 的
_maps.scss、_mixins.scss和_root.scss文件 -
Bootstrap 5 可选部分文件的导入,用于布局、内容、表单和组件
-
Bootstrap 5 的
_helpers.scss文件导入 -
Bootstrap 5 的
_utilities.scss文件导入 -
导入我们自己的
_utilities.scss文件,该文件用于定义我们想要使用实用 API 生成的实用工具 -
Bootstrap 5 的
utilities/_api.scss文件导入,用于生成实用类 -
导入我们自己的
_custom-styles.scss文件,该文件用于添加任何额外的自定义 SCSS
接下来,您将看到所有@import语句的代码(有关我们自己的文件的注释和@import语句的代码已被突出显示):
part-2/chapter-8/website/scss/style.scss
// Required
@import "../../../../bootstrap/scss/functions";
// Default variable overrides
@import "default-variable-overrides";
// Required
@import "../../../../bootstrap/scss/variables";
// Variable value using existing variable
@import "variable-value-using-variable";
// Required
@import "../../../../bootstrap/scss/maps";
@import "../../../../bootstrap/scss/mixins";
@import "../../../../bootstrap/scss/root";
// Optional Bootstrap CSS
@import "../../../../bootstrap/scss/reboot";
@import "../../../../bootstrap/scss/type";
@import "../../../../bootstrap/scss/images";
@import "../../../../bootstrap/scss/containers";
@import "../../../../bootstrap/scss/grid";
@import "../../../../bootstrap/scss/tables";
@import "../../../../bootstrap/scss/forms";
@import "../../../../bootstrap/scss/buttons";
@import "../../../../bootstrap/scss/transitions";
@import "../../../../bootstrap/scss/dropdown";
@import "../../../../bootstrap/scss/button-group";
@import "../../../../bootstrap/scss/nav";
@import "../../../../bootstrap/scss/navbar";
@import "../../../../bootstrap/scss/card";
@import "../../../../bootstrap/scss/accordion";
@import "../../../../bootstrap/scss/breadcrumb";
@import "../../../../bootstrap/scss/pagination";
@import "../../../../bootstrap/scss/badge";
@import "../../../../bootstrap/scss/alert";
@import "../../../../bootstrap/scss/progress";
@import "../../../../bootstrap/scss/list-group";
@import "../../../../bootstrap/scss/close";
@import "../../../../bootstrap/scss/toasts";
@import "../../../../bootstrap/scss/modal";
@import "../../../../bootstrap/scss/tooltip";
@import "../../../../bootstrap/scss/popover";
@import "../../../../bootstrap/scss/carousel";
@import "../../../../bootstrap/scss/spinners";
@import "../../../../bootstrap/scss/offcanvas";
@import "../../../../bootstrap/scss/placeholders";
// Helpers
@import "../../../../bootstrap/scss/helpers";
// Utilities
@import "../../../../bootstrap/scss/utilities";
// Define utilities
@import "utilities";
// Utilities API
@import "../../../../bootstrap/scss/utilities/api";
// Own custom styles
@import "custom-styles";
我们现在准备好开始定制我们的网站,并将自定义代码添加到我们自己的四个不同文件中。
我们将从_default-variable-overrides.scss文件中的默认变量覆盖代码开始。
默认变量覆盖
_default-variable-overrides.scss
在此文件中,我们将添加有关颜色、全局选项、全局变量和布局的所有自定义代码,以及一些有关表单和组件的自定义代码。在_variable-value-using-variable.scss文件中也会有关于表单和组件的自定义代码(以及其他自定义代码),我们将在本章稍后更详细地研究这个文件。
调色板
我们首先想做的事情是定义我们自己的调色板。与我们在本章稍后将要定制的排版一起,这是定义品牌视觉设计的一个重要方面。
我们通过分配新的十六进制颜色值来覆盖所有上下文颜色类,但可以使用其他任何方式来定义颜色。注释中提到的$secondary、$light和$dark变量被分配了 Bootstrap 5 中定义的灰色颜色列表中的颜色值。灰色颜色的变量尚未导入,因此我们无法将它们用作$secondary、$light和$dark的值:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 第 1-10 行
// Color palette
$primary: #0464a1;
$secondary: #adb5bd; // = $gray-500
$success: #2A9D8F;
$info: #E9C46A;
$warning: #F4A261;
$danger: #E76F51;
$light: #dee2e6; // = $gray-300
$dark: #343a40; // $gray-800
在定义了我们自己的调色板之后,我们现在将转到更改全局选项之一。
全局选项
对于这个网站,我们只想更改 Bootstrap 5 的阴影选项。我们将它设置为true以向各种组件添加阴影:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 第 12-14 行
// Shadows
$enable-shadows: true;
全局变量
全局变量是用于在其他许多地方作为其他变量值的变量。影响最大的全局变量是间距和边框半径的变量,我们现在将更改这些变量。
间距
我们可以通过修改$spacer变量来更改许多 Bootstrap 5 元素的默认样式,并且我们可以通过修改$spacers映射来控制间距实用工具的值。
我们将使用以下代码中看到的新的间距值:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 17-26
// Spacer
$spacer: 1.5rem;
$spacers: (
0: 0,
1: $spacer / 4,
2: $spacer / 2,
3: $spacer,
4: $spacer * 2,
5: $spacer * 4,
);
增加间隔会影响 Bootstrap 5 的许多元素,包括与响应式网格系统一起使用的网格间隔实用工具。为了在使用嵌套网格系统时在列之间获得更多一致的间距,我们将主页(在热门产品模块中)、商店页面(在产品概览模块中)、产品页面(在相关产品模块中)和愿望单页面(在产品概览模块中)上使用的.g-4类更改为.g-3。
另一项我们需要进行的微小调整是将产品页面中<blockquote>元素中包裹引用图标的三 <div> 元素上的.mt-2类更改为.mt-1。请参见此处代码更改:
part-2/chapter-8/website/product.xhtml
// Original code
<div class="text-secondary float-start fs-1 lh-1 mt-2 me-2 border-top border-start border-2 border-secondary p-1"><i class="bi-quote"></i></div>
// Updated code
<div class="text-secondary float-start fs-1 lh-1 mt-1 me-2 border-top border-start border-2 border-secondary p-1"><i class="bi-quote"></i></div>
边框半径
我们还可以通过修改与边框半径相关的三个变量来更改许多 Bootstrap 5 元素的默认样式:$border-radius、$border-radius-sm和$border-radius-lg。最后一个边框半径变量$border-radius-pill仅用于边框实用工具,因此我们不会更改它。
最激进的改变将是将所有变量设置为0,以从所有元素中移除边框半径并拥有直角,但我们将加倍默认边框半径并对其他两个变量进行轻微调整:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 28-31
// Border radius
$border-radius: .5rem;
$border-radius-sm: .25rem;
$border-radius-lg: .75rem;
布局
可以调整布局的样式,包括断点、容器和网格系统。如果我们更改网格系统中的列数,将需要在我们的 HTML 页面中的网格系统标记上进行大量更改,因此我们将坚持更改网站中的断点和容器。
断点
断点设置用于网格系统和容器,以及以下具有响应式变化的元素:下拉菜单、列表组、模态框、导航栏、表格和位置辅助工具。
我们将每个断点增加 40 像素,使我们的网格系统与默认 Bootstrap 5 设置略有不同:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 34-42
// Breakpoints
$grid-breakpoints: (
xs: 0,
sm: 616px,
md: 808px,
lg: 1032px,
xl: 1240px,
xxl: 1440px
);
容器
由于我们增加了断点大小 40 像素,我们还将增加容器最大宽度大小 40 像素。没有必要用相同的值同时更改网格断点和容器最大宽度,但你应该确保在更改任何这些值时进行测试:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 44-51
// Container
$container-max-widths: (
sm: 580px,
md: 760px,
lg: 1000px,
xl: 1180px,
xxl: 1360px
);
我们现在已经对 Bootstrap 5 的布局进行了几项更改,并将继续自定义表单。
表单
输入框和按钮已经受到我们之前更改的全球边框半径变量的影响,但不受全球填充变量的影响。因此,我们将调整输入框和按钮的垂直和水平填充。它们共享相同的填充、字体、焦点状态和边框宽度变量,所以我们只需要在一个地方覆盖填充即可影响输入框和按钮:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 53-56
// Inputs and buttons
$input-btn-padding-y: .5rem;
$input-btn-padding-x: 1em;
组件
在以下内容中,我们将更改我们网站中使用的某些组件的各种属性。
面包屑
对于面包屑组件,我们将更改面包屑分隔符的符号:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 59-60
// Breadcrumb
$breadcrumb-divider: quote("–");
轮播
对于轮播组件,我们将增加每侧的控制图标宽度,并增加指示器的高度和间距:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 62-65
// Carousel
$carousel-control-icon-width: 4rem;
$carousel-indicator-height: 10px;
$carousel-indicator-spacer: 10px;
下拉菜单
对于下拉菜单组件,我们将设置最小宽度为 0,这样当下拉菜单项不包含太多文本时,它不会占用额外的水平空间:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 67-68
// Dropdown
$dropdown-min-width: 0;
模态框
对于模态框组件,我们将增加大型模态框的大小,增加背景的透明度,并改变其打开和关闭时的过渡效果:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 70-73
// Modal
$modal-lg: 900px;
$modal-backdrop-opacity: .75;
$modal-fade-transform: rotate(5deg) scale(.9);
导航栏
对于导航栏组件,我们将增加导航链接的垂直填充,使其更大:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 75-76
// Navs
$nav-link-padding-y: 1rem;
进度条
对于进度条组件,我们将增加其高度,减少动画持续时间,并减少过渡持续时间:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 78-81
// Progress
$progress-height: 2rem;
$progress-bar-animation-timing: .5s linear infinite;
$progress-bar-transition: width .4s ease;
旋转器
对于旋转器组件,我们将增加动画持续时间,使其旋转速度稍微慢一些:
part-2/chapter-8/website/scss/_default-variable-overrides.scss 行 83-84
// Spinner
$spinner-animation-speed: 1s;
我们现在已经完成了所有关于默认变量覆盖的自定义设置,因此我们将继续使用现有变量进行进一步的变量值自定义。
使用现有变量设置变量值
_variable-value-using-variable.scss
在此文件中,我们将添加关于内容的所有自定义代码,关于表单和组件的一些自定义代码,以及一个辅助类的自定义代码。我们之所以在导入所需的 Bootstrap 5 _variables.scss 文件之后导入此文件,是因为我们希望使用 _variables.scss 中的现有变量作为覆盖与内容、某些表单和组件变量以及一个辅助类变量相关联的新值。这在我们需要将颜色变量分配给其他变量时特别有用。
_variable-value-using-variable.scss文件中的某些代码不必放在那里,也可以放在_default-variable-overrides.scss文件中。但是,我选择尽可能地将相关的变量分组在一起,这就是为什么所有与内容相关的变量都集中在这里。
内容
Bootstrap 5 的内容类别包括排版、图片、表格和图表。我们将对其中所有内容进行更改,除了表格。
排版
如前所述,排版是视觉设计的一个重要方面。因此,我们将对整体排版进行重大更改。
首先,我们将使用这两个来自 Google Fonts 的免费字体:Roboto 和 Comfortaa。这可以通过在所有 HTML 文件的</head>标签之前添加以下三个<link>标签来实现:
*.xhtml 行 9-11
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@300;500&family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
现在可以使用两个 Google Fonts 字体,它们将被添加到下一个代码块中的$font-family-base和$headings-font-family变量中。
这里是我们对排版所做的所有更改的概述:
-
<body>的背景颜色和文本颜色 -
默认字体家族、字体大小和行高
-
链接的样式
-
正常标题的字体家族、字体大小、字体粗细、行高和底部外边距
-
显示标题的字体大小和行高
-
首段文字的字体大小
看看以下代码中是如何实现所有这些更改的:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 2-37
// Typograhy
// Body styles
$body-bg: $gray-100;
$body-color: $gray-700;
// Basic typography styles
$font-family-base: 'Roboto', sans-serif;
$font-size-base: 1.125rem;
$line-height-base: 1.4;
$line-height-sm: 1.2;
// Link styles
$link-decoration: none;
$link-hover-color: shift-color($link-color, $link-shade-percentage);
$link-hover-decoration: underline;
// Heading styles
$headings-font-family: 'Comfortaa', cursive;
$h1-font-size: $font-size-base * 3;
$h2-font-size: $font-size-base * 2.5;
$h3-font-size: $font-size-base * 2;
$h4-font-size: $font-size-base * 1.75;
$h5-font-size: $font-size-base * 1.5;
$h6-font-size: $font-size-base * 1.25;
$headings-font-weight: $font-weight-bold;
$headings-line-height: $line-height-sm;
$headings-margin-bottom: $spacer * 0.25;
// Display styles
$display-font-sizes: (
1: $h1-font-size * 1.5,
2: $h2-font-size * 1.5,
3: $h3-font-size * 1.5,
4: $h4-font-size * 1.5,
5: $h5-font-size * 1.5,
6: $h6-font-size * 1.5
);
$display-line-height: $headings-line-height;
// Lead styles
$lead-font-size: $font-size-base * 1.375;
图片
对于图片,我们将对图像缩略图进行一些更改。我们将增加填充,更改背景颜色,更改边框颜色,并减小边框半径:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 39-43
// Images
$thumbnail-padding: .5rem;
$thumbnail-bg: $body-bg;
$thumbnail-border-color: $gray-500;
$thumbnail-border-radius: $border-radius-sm;
注意,我们刚刚将图像缩略图的背景颜色设置为我们在前面的排版代码块中更改的<body>的背景颜色。我们将使用该变量($body-bg)或相关的变量(用于<body>文本颜色的$body-color)来对所有剩余的此文件中的自定义进行修改。
图表
对于图表,我们将增加字体大小并更改图表标题的文本颜色:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 45-47
// Figures
$figure-caption-font-size: $font-size-lg;
$figure-caption-color: $body-color;
表单
我们将设置输入元素、复选框、单选按钮和选择元素的背景颜色。我们首先将$body-bg值分配给$input-bg,然后使用该变量($input-bg)作为$form-check-input-bg和$form-select-bg变量的值:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 49-53
// Form controls
$input-bg: $body-bg;
$form-check-input-bg: $input-bg;
$form-select-bg: $input-bg;
组件
如您接下来所见,我们将放置那些需要$body-bg变量作为背景颜色值的组件变量(在此文件和内容自定义之后)。
卡片
对于卡片组件,我们将更改背景颜色:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 56-57
// Card
$card-bg: $body-bg;
列表组
对于列表组组件,我们将更改背景颜色:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 59-60
// List group
$list-group-bg: $body-bg;
辅助类
由于辅助类不能使用 _variables.scss 文件中的变量进行自定义,因为它们没有与 Bootstrap 5 元素相同的视觉属性,所以不能使用变量进行自定义。例外的是比率辅助类,我们将在下一节中看到。
比率
比率辅助类是从 $aspect-ratios Sass 映射生成的。我们可以通过将其与自定义映射合并来向此映射添加更多值:
part-2/chapter-8/website/scss/_variable-value-using-variable.scss 行 62-69
// Ratio
// Create custom ratio map
$custom-ratio: (
"5x3": calc(3 / 5 * 100%)
);
// Merge "$aspect-ratios" and "$custom-ratio"
$aspect-ratios: map-merge($aspect-ratios, $custom-ratio);
在前面的代码中,通过新的属性和宽高比 5 比 3 创建了新的 $custom-ratio Sass 映射。该值基于与 $aspect-ratios Sass 映射中现有值相同的计算。当这些映射合并时,我们现在得到了新的 .ratio-5x3 辅助类。在此更改之后,我们需要更新已经在我们的联系页面使用的比率辅助类,如下所示:
part-2/chapter-8/website/contact.xhtml
// Original code
<div class="ratio ratio-21x9">
<iframe src="img/[URL for Google Maps embed]"
allowfullscreen></iframe>
</div>
// Updated code
<div class="ratio ratio-5x3">
<iframe src="img/[URL for Google Maps embed]"
allowfullscreen></iframe>
</div>
我们现在已经完成了所有辅助类的自定义,因此我们将继续自定义实用程序。
实用程序
_utilities.scss
在此文件中,我们将添加所有使用实用程序 API 的自定义代码。一些实用程序已经进行了自定义,因为它们的值基于 _variables.scss 文件中的变量,我们已经在本章前面覆盖了这些变量。这包括间距实用程序和各种文本实用程序。额外的自定义需要使用实用程序 API 的代码。
在使用实用程序 API 修改任何实用程序之前,我们应该考虑我们已经在使用的哪些实用程序在当前形式下不足或不灵活,然后进行修改。
对于我们的网站,我们将在购物车页面改进两个方面。首先,我们希望通过使用更灵活的边框实用程序来改进摘要部分运输详情标签页和支付选项标签页中围绕我们的产品概览的 <div> 元素中元素的响应式布局。
由于我们不仅修改了一些实用程序的值,而且使它们更加灵活,从而生成了我们可以使用的更多实用程序类,因此我们还需要相应地更新 HTML。
尺寸
我们想改变 width 的尺寸实用程序,以便更好地控制断点之间的一些元素的布局。我们将使 width 的实用程序响应式,并使用以下代码添加额外的属性和值 33: 33% 和 67: 67%:
part-2/chapter-8/website/scss/_utilities.scss 行 1-20
// Make sizing utilities for width responsive and add extra
// values
$utilities: map-merge(
$utilities,
(
"width": (
property: width,
responsive: true,
class: w,
values: (
25: 25%,
33: 33%,
50: 50%,
67: 67%,
75: 75%,
100: 100%,
auto: auto
)
)
)
);
这将生成大量的新响应式 width 实用程序类以及我们添加的新属性和值的类,因此我们现在将按以下方式更新我们的 HTML:
part-2/chapter-8/website/cart.xhtml
// Original code
<div class="d-flex align-items-start me-3 mb-3 mb-md-0">[code for product]</div>
<div class="d-flex">
<div class="input-group w-auto me-3">[code for input
group]</div>
[code for remove button]
</div>
// Updated code
<div class="d-flex align-items-start me-3 mb-3 mb-md-0 w-md-67 w-lg-75 w-xl-67 w-xxl-75">[code for product]</div>
<div class="d-flex w-75 w-sm-50 w-md-33 w-lg-25 w-xl-33 w-xxl-25">
<div class="input-group w-auto me-3">[code for input
group]</div>
[code for remove button]
</div>
在前面的代码中,我们现在分别为我们布局的两个不同部分使用 4 和 6 个宽度实用工具类。如果我们看第二部分,我们可以看到我们在调整每个现有断点的宽度。这在处理响应式设计时有时是必要的,以获得最佳可能的布局。
边框
我们希望改进 <div> 元素在 xs、sm、xl 和 xxl 断点上的边框使用,并在 md 和 lg 断点之间转换为两列网格。我们希望对于 md 和 lg 断点,边框放置在右侧,对于所有其他断点,放置在底部。
为了实现这一点,我们需要使 border-width、border-bottom 和 border-end 的边框实用工具响应式,我们可以通过以下代码来完成:
part-2/chapter-8/website/scss/_utilities.scss 行 22-38
// Make border utilities for border-width, border-bottom
// and border-end responsive
$utilities: map-merge(
$utilities, (
"border-width": map-merge(
map-get($utilities, "border-width"),
( responsive: true ),
),
"border-bottom": map-merge(
map-get($utilities, "border-bottom"),
( responsive: true ),
),
"border-end": map-merge(
map-get($utilities, "border-end"),
( responsive: true ),
),
)
);
这将生成大量的新响应式边框实用工具类,因此我们现在需要更新我们的 HTML。我们还将使用间距实用工具来优化页面该部分的填充和边距布局,结果如下所示:
part-2/chapter-8/website/cart.xhtml
// Original code
<div class="border-bottom border-2 border-light mb-4 pb-4">[code for products]</div>
// Updated code
<div class="border-bottom border-2 border-light mb-4 pb-4 border-bottom-md-0 border-end-md border-md-2 pb-md-0 mb-md-0 border-bottom-xl border-end-xl-0 border-xl-2 pb-xl-4 mb-xl-4">[code for products]</div>
我们已经为实用工具完成了所有自定义设置,因此我们将继续进行其他自定义样式的设置。
其他自定义样式
_custom-styles.scss
在此文件中,我们将添加所有无法通过覆盖 _variables.scss 文件中现有变量的组件的自定义代码。相反,我们将使用 CSS 类选择器针对组件,并使用常规 CSS 和 Sass 代码的组合来修改样式。即使我们无法覆盖现有变量,我们仍然可以将它们用作 CSS 属性的值,我们将为此部分中的两个组件这样做。
警报
我们希望在 alert 组件的左侧添加一个粗边框,边框颜色继承文本颜色,厚度是 $spacer 变量值的一半:
part-2/chapter-8/website/scss/_custom-styles.scss 行 1-4
// Customize the left border of the alert component
.alert {
border-left: ($spacer * .5) solid;
}
前面代码中使用的 border-left 简写等于以下内容:
border-left-width: $spacer * .5;
border-left-style: solid;
border-left-color: currentColor;
由于默认的 currentColor 边框颜色值,左侧边框的颜色将继承警报文本颜色的颜色,这取决于所使用的警报类型。在我们的网站上,我们目前使用 $info 颜色上的信息警报。
抽屉式布局
我们希望将 _variables.scss 文件的头信息作为我们的 CSS 属性的值。这导致了以下代码:
part-2/chapter-8/website/scss/_custom-styles.scss 行 6-10
// Customize the background color and bottom border of the
// header of the offcanvas component
.offcanvas-header {
background-color: $card-cap-bg;
border-bottom: $card-border-width solid $card-border-color;
}
摘要
在本章中,我们学习了与真实网站相关的 Bootstrap 5 定制在实际中的工作方式。首先,我们学习了如何混合和排序 Bootstrap 5 Sass 部分和我们的自定义 Sass 部分的@import语句,以实现最大的定制性。然后,我们学习了如何使用 Bootstrap 5 变量来定制布局、内容、表单、组件和辅助元素。接着,我们学习了如何使用实用 API 修改现有实用工具,使它们更加灵活并改善我们网站的布局。最后,我们学习了如何使用我们自己的 Sass 代码以不同于默认方式的方式来定制组件。
在下一章中,我们将看到如何进一步改进和扩展我们的网站,包括如何添加自定义组件和添加交互功能。
第九章:第九章:使用 JavaScript 改进网站交互功能
在本章中,我们将学习如何使用不同的交互功能来改进我们的网站。这些功能将使用 JavaScript 创建,在大多数情况下,将使用基于 Bootstrap 5 的 JavaScript 组件。在前一章中,我们自定义了网站的外观 – 在本章中,我们将自定义网站的感觉。
Bootstrap 5 有几个使用 JavaScript 的交互组件。其中一些组件通过使用数据属性自动初始化,例如,手风琴、轮播图、下拉菜单、侧边栏、导航栏、模态框和标签页组件,这些我们目前在网站上正在使用。其他组件需要使用 JavaScript 进行自定义初始化,例如弹出框、通知和工具提示组件。表单验证需要在正确的时间执行自定义 JavaScript,而旋转器组件应在浏览器处于加载状态时才可见。正如你所看到的,Bootstrap 5 中 JavaScript 以不同的方式用于不同的目的。
在本章中,我们将看到如何使用 JavaScript 来改进我们的网站,以下场景将使用交互功能:
-
向表单标签添加工具提示组件
-
向与产品相关的操作添加通知组件
-
在购物车表单中更改产品数量
-
添加表单验证
-
添加表单提交加载指示器
-
添加表单成功消息
-
创建程序化标签导航
-
更新结账流程中的进度状态
-
为产品画廊创建灯箱
所有这些场景都将影响我们网站各个部分或组件的感觉和行为,这就是为什么它们被包含在本章中的原因。
技术要求
-
要预览示例,你需要一个代码编辑器和浏览器。所有代码示例的源代码可以在以下位置找到:
github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide -
要将 Sass 编译为 CSS,你需要以下之一:
-
Node.js,如果你更喜欢使用终端(Mac)或命令提示符(Windows)的命令行界面(CLI)
-
Scout-App,如果你更喜欢使用图形用户界面(GUI)
-
Visual Studio Code,如果你更喜欢使用 Visual Studio Code 市场中的扩展
-
所有这些方法都在第二章 使用和编译 Sass中进行了解释。
关于代码示例
在我们接下来更详细地查看即将到来的各个示例之前,这里有一些关于代码示例的注意事项,提前了解这些内容会很有帮助。我鼓励你使用自己的编辑器查看本章中每个代码示例提到的各种文件,以便你可以亲自看到这些变化。此外,我也鼓励你通过浏览器查看项目,以便你可以体验所做的改进。本章是关于交互式功能的,所以要看到它带来的真正差异,必须在浏览器中查看。
简单和干净的 JavaScript 代码
网站的定制 JavaScript 代码是用简单和干净的 JavaScript 编写的。重点是使其易于理解,而不一定是最佳实践。所有代码都在 bootstrap.bundle.min.js Bootstrap 5 JavaScript 文件之后放置在同一个 script.js 文件中。
页面 ID
页面 ID 已添加到 <body> 标签上的 script.js,通常根据代码应执行的页面或页面组进行分组,并且它们也以本章中展示的大致相同顺序出现。
<body> 标签上的更新代码看起来如下:
part-2/chapter-9/website/index.xhtml 行 13
<body id="homePage">
part-2/chapter-9/website/shop.xhtml 行 13
<body id="shopPage">
part-2/chapter-9/website/product.xhtml 行 13
<body id="productPage">
part-2/chapter-9/website/contact.xhtml 行 13
<body id="contactPage">
part-2/chapter-9/website/wishlist.xhtml 行 13
<body id="wishlistPage">
part-2/chapter-9/website/cart.xhtml 行 13
<body id="cartPage">
以下是使用这些 ID 的条件 if 语句的示例说明:
part-2/chapter-9/website/js/script.js
// Variables for individual pages
const homePage = document.querySelector('#homePage'); // index.xhtml
// Used like this for one page only
if (homePage) {
[code added here]
}
// Used like this for multiple pages
if (homePage || shopPage || productPage) {
[code added here]
}
由于我希望页面变量的条件if语句尽可能简单,所以代码示例中不会展示这些语句。实际上,源代码中的if语句可以忽略。它们对于理解如何实现各种交互式功能不是必需的,但“只是”用于处理代码的不同部分执行时,以避免“破坏”代码。
部分和完整代码
在本章中,一些代码示例可能不会看起来像是完整和完成的源代码。这是因为,对于一些交互式功能,作为一个起点,我会向你展示所需的最少代码。然后,在之后,当我们添加更多功能时,我会将新代码添加到现有的代码示例中。选择这种方法是为了逐步引导你了解代码的工作原理。
当一个代码示例更新为另一个功能的新代码时,新代码将被突出显示。以下是一个说明这意味着什么的示例:
script.js
this is the minimum required code
for an interactive feature
this is new code
for another feature that we add to
the existing code example
that we can think of as partial code
原始和更新代码
一些代码示例展示了原始代码(来自第八章**,使用 Bootstrap 5 变量、实用 API 和 Sass 自定义网站*)和更新的新代码。代码将以相同的代码块并排展示,更新的代码将突出显示,如下所示:
script.js
// Original code
<label for="securityCode">Lorem ipsum</label>
// Updated code
<label class="form-label d-flex justify-content-between" for="securityCode">Lorem ipsum</label>
行号
为了使源代码的导航更简单,大多数代码示例都添加了行号,以及文件路径。这对于 JavaScript 和 Sass 代码示例尤其如此,但也包括一些 HTML 代码示例。
将工具提示组件添加到表单标签
现在我们将在购物车页面上的结账流程中的表单标签处添加一个工具提示组件,为用户提供一些在鼠标悬停(或在触摸设备上轻触)时触发的有用上下文信息。我们将把这个工具提示组件添加到位于表单中支付选项标签页的信用卡安全码输入旁边的图标上。
我们需要做的第一件事是添加适当的标记。在标签文本之后,我们将添加一个.bi-question-circle图标,并用.text-info着色,然后在这个图标中放入我们工具提示组件所需的属性。我们的标记将按以下方式更新:
part-2/chapter-9/website/cart.xhtml
// Original code
<label class="form-label d-flex justify-content-between" for="securityCode">Security code:</label>
// Updated code
<label class="form-label d-flex justify-content-between" for="securityCode">Security code: <i class="bi-question-circle text-info" data-bs-toggle="tooltip" title="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis convallis velit quis sapien sollicitudin ultrices."></i></label>
工具提示组件不是通过使用data-bs-toggle="tooltip"自动初始化的,这是我们可能期望的。相反,出于性能原因,工具提示组件必须由我们自己初始化。因此,我们将添加以下 JavaScript,它将使用Tooltip()构造函数初始化页面上的所有工具提示组件:
part-2/chapter-9/website/js/script.js 行 3-7
// Initialize all tooltips
const tooltipTriggerElements = document.querySelectorAll('[data-bs-toggle="tooltip"]');
for (let i = 0; i < tooltipTriggerElements.length; i++) {
new bootstrap.Tooltip(tooltipTriggerElements[i])
}
通过这些更改,你将能够在浏览器中看到新的图标和工具提示组件的实际效果。目前,我们网站上只有一个工具提示,所以我们本可以选择另一种实现方式,但我喜欢这种方式,因为它可以容纳我们可能稍后选择添加的任何额外工具提示。
将 toast 组件添加到与产品相关的操作
现在,我们将添加由不同的产品相关操作触发的 toast 组件,例如,当在首页、商店、购物车、产品和愿望单页面的产品卡片底部点击操作按钮时。
在创建单个 toast 组件之前,我们将向之前提到的每个页面添加一个 toast 容器,位于打开的<body>标签之后和<header>标签之前。我们将使用以下代码:
<div class="toast-container position-fixed end-0 mt-3 me-3"></div>
现在,我们遇到了一个问题,即 toast 容器不会沿着我们布局的 z 轴正确定位。页面上的其他组件将被放置在顶部,而这不是我们想要的。这是 navbar、按钮组和下拉组件的情况。我们将通过在我们的自定义样式表中使用以下 Bootstrap 5 z-index变量之一来解决这个问题:
bootstrap/scss/_variables.scss
1068 $zindex-dropdown: 1000 !default;
1069 $zindex-sticky: 1020 !default;
1070 $zindex-fixed: 1030 !default;
1071 $zindex-offcanvas-backdrop: 1040 !default;
1072 $zindex-offcanvas: 1045 !default;
1073 $zindex-modal-backdrop: 1050 !default;
1074 $zindex-modal: 1055 !default;
1075 $zindex-popover: 1070 !default;
1076 $zindex-tooltip: 1080 !default;
从前面的列表中,我们可以看到$zindex-fixed变量将是一个很好的选择。这是因为我们的 toast 容器已经使用了.position-fixed类,我们希望它在我们的页眉中的货币下拉菜单上方显示,并在 offcanvas 背景下方。然后,我们可以在我们的自定义样式表中添加以下 Sass 代码:
part-2/chapter-9/website/scss/_custom-styles.scss 行 12-15
// Add z-index to get the right position along the z-axis
.toast-container {
z-index: $zindex-fixed;
}
我们将在以下场景中使用吐司组件:
-
将产品添加到购物车
-
将产品添加到心愿单
-
将所有产品添加到购物车
-
从心愿单中移除产品
-
从购物车中移除产品
我们将逐一查看所有这些内容。
将产品添加到购物车
当用户点击位于首页、商店、产品和心愿单页面产品卡片页脚中的添加到购物车按钮时,我们希望显示一个吐司组件。
首先,我们将向所有上述页面上的吐司容器中添加以下标记:
part-2/chapter-9/website/index.xhtml
<div class="toast js-cartToast" role="status" aria-live="polite" aria-atomic="true">
<div class="toast-header fw-bold">Added to cart</div>
<div class="toast-body">Product Name was added to the
cart.</div>
</div>
注意在前面代码中,我们已经将.js-cartToast类添加到 Bootstrap 5 代码中,用于默认的吐司组件。我们将使用它作为初始化吐司组件时使用的 JavaScript 的钩子。
在我们这样做之前,我们还需要更新我们的.js-addToCart类,作为我们的 JavaScript 钩子:
part-2/chapter-9/website/index.xhtml
<button type="button" class="btn btn-primary me-2 js-addToCart">
<i class="bi-cart-plus"></i><span class=
"visually-hidden">Add to cart</span>
</button>
现在,当点击以下 JavaScript 代码中的任何添加到购物车按钮时,我们可以使用Toast()构造函数和show()方法来显示吐司组件:
part-2/chapter-9/website/js/script.js 行 20-27
// Handle button click and show toast when adding product
// to cart
const addToCartButtons = document.querySelectorAll('.js-addToCart');
const addToCartToast = document.querySelector('.js-cartToast');
for (let i = 0; i < addToCartButtons.length; i++) {
addToCartButtons[i].addEventListener('click', function() {
new bootstrap.Toast(addToCartToast).show();
})
}
使用 JavaScript 方法与交互式 Bootstrap 5 组件
在本章的交互式功能中,show()方法将被多次使用。我们将在第十一章“使用具有高级 JavaScript 功能的 Bootstrap 5”中学习如何使用 JavaScript 方法与交互式 Bootstrap 5 组件一起使用。
将产品添加到心愿单
当用户点击位于首页、商店和产品页面产品卡片页脚中的添加到心愿单下拉菜单中的按钮时,我们希望显示一个吐司组件。
首先,我们将向所有上述页面上的吐司容器中添加以下标记:
part-2/chapter-9/website/index.xhtml
<div class="toast js-wishlistToast" role="status" aria-live="polite" aria-atomic="true">
<div class="toast-header fw-bold">Added to wishlist</div>
<div class="toast-body">Product Name was added to the
wishlist.</div>
</div>
注意在前面代码中,我们已经将.js-wishlistToast类添加到 Bootstrap 5 代码中,用于默认的吐司组件。我们将使用它作为初始化吐司组件时使用的 JavaScript 的钩子。
在我们这样做之前,我们还需要更新.js-addToWishlist类中的按钮,作为我们的 JavaScript 钩子:
part-2/chapter-9/website/index.xhtml
<div class="dropdown">
<button type="button" class="btn btn-secondary"
id="addToWishlistDropdown1" data-bs-toggle="dropdown"
aria-expanded="false"><i class="bi-heart"></i><span
class="visually-hidden">Add to wishlist</span></button>
<div class="dropdown-menu" aria-
labelledby="addToWishlistDropdown1">
<h6 class="dropdown-header">Select wishlist</h6>
<button type="button" class="dropdown-item js-
addToWishlist">Wishlist #1</button>
<button type="button" class="dropdown-item js-
addToWishlist">Wishlist #2</button>
<button type="button" class="dropdown-item js-
addToWishlist">Wishlist #3</button>
</div>
</div>
现在,当点击任何添加到心愿单下拉菜单中的按钮时,我们可以使用以下 JavaScript 代码来初始化吐司组件:
part-2/chapter-9/website/js/script.js 行 34-41
// Handle button click and show toast when adding product
// to wishlist
const addToWishlistButtons = document.querySelectorAll('.js-addToWishlist');
const addToWishlistToast = document.querySelector('.js-wishlistToast');
for (let i = 0; i < addToWishlistButtons.length; i++) {
addToWishlistButtons[i].addEventListener('click',
function() {
new bootstrap.Toast(addToWishlistToast).show();
})
}
将所有产品添加到购物车
当用户点击心愿单页面中的<aside>元素时,我们希望显示一个吐司组件。
首先,我们将向该页面的吐司容器中添加以下标记:
part-2/chapter-9/website/wishlist.xhtml
<div class="toast js-addAllToast" role="status" aria-live="polite" aria-atomic="true">
<div class="toast-header fw-bold">All added to cart</div>
<div class="toast-body">All products from wishlist were
added to the cart.</div>
</div>
注意在前面代码中,我们已经为 Bootstrap 5 代码添加了.js-addAllToast类以创建默认的吐司组件。我们将使用这个类作为初始化吐司组件的 JavaScript 钩子。
在此之前,我们还需要更新.js-addAllToCart类作为 JavaScript 的钩子:
part-2/chapter-9/website/wishlist.xhtml
<button type="button" class="btn btn-primary mt-3 js-addAllToCart">Add all products to cart</button>
现在,当点击将所有产品添加到购物车按钮时,我们可以使用以下 JavaScript 代码初始化吐司组件:
part-2/chapter-9/website/js/script.js 行 48-53
// Handle button click and show toast when adding all
// products to cart
const addAllToCartButton = document.querySelector('.js-addAllToCart');
const addAllToCartToast = document.querySelector('.js-addAllToast');
addAllToCartButton.addEventListener('click', function() {
new bootstrap.Toast(addAllToCartToast).show();
})
从愿望单中移除产品
我们希望在用户点击位于愿望单页面产品卡片页脚的从愿望单移除按钮时显示一个吐司组件。同时,我们还想从页面上移除产品卡片以及相关的 DOM 标记。
首先,我们将添加以下标记到该页面的吐司容器中:
part-2/chapter-9/website/wishlist.xhtml
<div class="toast js-wishlistToast" role="status" aria-live="polite" aria-atomic="true">
<div class="toast-header fw-bold">Removed from
wishlist</div>
<div class="toast-body">Product Name was removed from the
wishlist.</div>
</div>
注意在前面代码中,我们已经为 Bootstrap 5 代码添加了.js-wishlistToast类以创建默认的吐司组件。我们将使用这个类作为初始化吐司组件的 JavaScript 钩子。
在此之前,我们还需要更新我们的.js-removeFromWishlist类作为 JavaScript 的钩子:
part-2/chapter-9/website/wishlist.xhtml
<button type="button" class="btn btn-danger js-removeFromWishlist">
<i class="bi-x-circle"></i><span class="visually-
hidden">Remove from wishlist</span>
</button>
现在,当点击任何从愿望单移除按钮时,我们可以初始化吐司组件,并使用以下 JavaScript 代码从 DOM 中移除元素:
part-2/chapter-9/website/js/script.js 行 55-63
// Handle button click and show toast + remove element from
// DOM when removing product from wishlist
const removeFromWishlistButtons = document.querySelectorAll('.js-removeFromWishlist');
const removeFromWishlistToast = document.querySelector('.js-wishlistToast');
for (let i = 0; i < removeFromWishlistButtons.length; i++) {
removeFromWishlistButtons[i].addEventListener('click',
function() {
new bootstrap.Toast(removeFromWishlistToast).show();
removeFromWishlistButtons[i].closest(
'.card').parentElement.remove();
})
}
从购物车中移除产品
在这里,我们希望在用户点击购物车页面购物车选项卡中的产品概览中的移除按钮时显示一个吐司组件。同时,我们还想从页面上移除产品以及相关的 DOM 标记。
首先,我们将添加以下标记到该页面的吐司容器中:
part-2/chapter-9/website/cart.xhtml
<div class="toast js-cartToast" role="status" aria-live="polite" aria-atomic="true">
<div class="toast-header fw-bold">Removed from cart</div>
<div class="toast-body">Product Name was removed from the
cart.</div>
</div>
注意在前面代码中,我们已经为 Bootstrap 5 代码添加了.js-cartToast类以创建默认的吐司组件。我们将使用这个类作为初始化吐司组件的 JavaScript 钩子。
在此之前,我们还需要通过添加.js-removeFromCart类作为 JavaScript 的钩子来更新我们的移除按钮:
part-2/chapter-9/website/cart.xhtml
<button type="button" class="btn btn-danger js-removeFromCart"><i class="bi-x-circle"></i></button>
现在,当任何移除按钮被点击时,我们可以初始化吐司组件,并使用以下 JavaScript 代码从 DOM 中移除元素:
part-2/chapter-9/website/js/script.js 行 71-78
// Handle button click and show toast + remove element from DOM when removing product from cart
const removeFromCartButtons = document.querySelectorAll('.js-removeFromCart');
const removeFromCartToast = document.querySelector('.js-cartToast');
for (let i = 0; i < removeFromCartButtons.length; i++) {
removeFromCartButtons[i].addEventListener('click',
function() {
new bootstrap.Toast(removeFromCartToast).show();
removeFromCartButtons[i].parentElement.
parentElement.remove();
})
}
现在,我们已经完成了向不同产品相关操作添加吐司组件的工作。接下来,我们将继续添加一个功能,用于更改购物车中单个产品的数量。
修改购物车中的产品数量
在购物车标签页中.js-productQuantity类的产品概览中,针对每个产品的输入组组件使用它作为我们的 JavaScript 的钩子。我们的输入组组件的标记将按以下方式更新:
part-2/chapter-9/website/cart.xhtml
<div class="input-group me-3 js-productQuantity">
<button type="button" class="btn btn-secondary"><i
class="bi-dash-circle"></i></button>
<input type="text" class="form-control text-center"
value="1" aria-label="Product quantity">
<button type="button" class="btn btn-secondary"><i
class="bi-plus-circle"></i></button>
</div>
现在我们可以使用以下 JavaScript 来减少数量(如果它大于1,因此它永远不会降到0或以下)或增加它:
part-2/chapter-9/website/js/script.js 行 81-94
// Handle button click on input group buttons and adjust
// value of input
const productQuantityInputGroup = document.querySelectorAll('.js-productQuantity');
for (let i = 0; i < productQuantityInputGroup.length; i++) {
let productQuantityInput =
productQuantityInputGroup[i].querySelector(
'.form-control');
const productQuantitySubtractButton =
productQuantityInputGroup[i].querySelectorAll(
'.btn')[0];
const productQuantityAddButton =
productQuantityInputGroup[i].querySelectorAll(
'.btn')[1];
productQuantitySubtractButton.addEventListener('click',
function() {
if (productQuantityInput.value > 1) {
productQuantityInput.value--;
}
})
productQuantityAddButton.addEventListener('click',
function() {
productQuantityInput.value++;
})
}
在添加此功能后,我们将继续为所有表单添加表单验证。
添加表单验证
Bootstrap 5 将表单验证作为其功能之一,因此我们想利用这一点来处理一些表单:主页上的新闻通讯表单,联系页面上的联系表单,以及购物车页面上的发货详情和支付选项标签页中的两个表单。
我们需要做的第一件事是为所有表单元素添加一个id属性,这样我们就可以从我们的 JavaScript 代码中定位它们。此外,我们还需要为表单元素添加novalidate属性,该属性用于禁用浏览器默认的反馈工具提示,同时仍然可以通过 JavaScript 访问表单验证。因此,我们需要对我们的标记进行以下更新:
part-2/chapter-9/website/index.xhtml 行 306
<form class="text-white" id="newsletterForm" novalidate>
part-2/chapter-9/website/contact.xhtml 行 185
<form id="contactForm" novalidate>
part-2/chapter-9/website/cart.xhtml 行 172
<form id="shippingForm" novalidate>
part-2/chapter-9/website/cart.xhtml 行 336
<form id="paymentForm" novalidate>
现在我们需要为有效和无效状态添加反馈信息。这将添加到具有所需属性的每个表单控件之后,并且我们希望在其中有反馈信息。我们不想在新闻通讯表单中的复选框添加此类反馈信息。这是因为有效和无效状态的样式足以让用户理解这种表单控件。
这是主页上新闻通讯表单的第一个表单字段的标记更新,以便容纳反馈信息:
part-2/chapter-9/website/index.xhtml
<div class="mb-3">
<label for="firstName" class="visually-hidden">First
name:</label>
<input type="text" class="form-control"
placeholder="Firstname" id="firstName" required>
<p class="valid-feedback">Valid feedback text</p>
<p class="invalid-feedback">Invalid feedback text</p>
</div>
在将这些反馈信息添加到所有我们希望在前面提到的所有表单字段中后,我们现在可以实施 JavaScript 中的表单验证。
首先,我们将表单存储在一个变量中,并监听表单的submit事件,该事件在点击提交按钮时触发。如果表单无效,我们将阻止表单提交;在此条件之外,将.was-validated类添加到表单中,以显示有效和无效状态的正确样式和反馈信息。
这是新闻通讯表单表单验证的 JavaScript 代码:
part-2/chapter-9/website/js/script.js 行 104-123
// Newsletter form
const newsletterForm = document.querySelector('#newsletterForm');
newsletterForm.addEventListener('submit', function (event) {
if (!newsletterForm.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
newsletterForm.classList.add('was-validated');
}, false)
在尝试提交无效表单后,每当用户更新表单中的任何表单字段时,都会再次运行验证。只有第一次验证不会运行,直到用户尝试提交表单。
添加表单提交加载指示器
我们希望为通讯录表单、联系表单和支付表单的表单提交添加加载指示器,这样用户可以看到浏览器正在等待服务器的响应。对于我们的网站,我们不会将任何表单提交到服务器或等待任何响应,因此我们将模拟这种行为。
我们的加载指示器将简单地是 Bootstrap 5 的旋转组件(更准确地说,是边框旋转变体),它将替换提交按钮的文本。
我们需要做的第一件事是为所有想要添加加载指示器的提交按钮添加一个id属性。然后,我们可以使用这些id属性在 JavaScript 代码中定位提交按钮。
这就是我们的提交按钮更新后的标记看起来像什么:
part-2/chapter-9/website/index.xhtml
<button type="submit" class="btn btn-primary" id="newsletterButton">Subscribe</button>
part-2/chapter-9/website/contact.xhtml
<button type="submit" class="btn btn-primary" id="contactButton">Submit</button>
part-2/chapter-9/website/cart.xhtml
<button type="submit" class="btn btn-primary" id="paymentButton">Pay</button>
我们将使用以下代码将旋转组件的标记添加到我们的 JavaScript 中的一个变量中:
part-2/chapter-9/website/js/script.js 行 98-100
// Markup for spinner component used on various forms
const spinnerMarkup = '<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Please wait...';
现在这个变量可以用来在我们需要时将旋转组件插入到我们的提交按钮中。
我们将在处理表单验证的脚本中添加加载指示器的代码。如果表单有效,首先,我们将阻止表单提交(以便我们可以模拟加载行为)。然后,我们将提交按钮的文本替换为旋转组件,并禁用提交按钮。之后,我们将使用setTimeout()方法模拟2000毫秒的加载时间,之后提交按钮内的旋转组件将被一些新的文本替换。
使用加载指示器的表单提交更新代码,再次以通讯录表单为例,现在看起来是这样的:
part-2/chapter-9/website/js/script.js 行 104-123
// Newsletter form
const newsletterForm = document.querySelector('#newsletterForm');
newsletterForm.addEventListener('submit', function (event) {
if (!newsletterForm.checkValidity()) {
event.preventDefault();
event.stopPropagation();
} else {
event.preventDefault();
const newsletterButton =
document.querySelector('#newsletterButton');
newsletterButton.innerHTML = spinnerMarkup;
newsletterButton.disabled = true;
setTimeout(function() {
const newsletterConfirmationText = 'Subscribed';
newsletterButton.innerHTML =
newsletterConfirmationText;
}, 2000)
}
newsletterForm.classList.add('was-validated');
}, false)
现在我们已经添加了表单提交加载指示器,但我们还有一个表单的交互特性。这是表单成功消息,我们将在下一个步骤中创建它。
添加表单成功消息
在上一个示例中,在表单提交完成后加载结束,提交按钮的文本被替换。现在我们希望在加载完成后,在我们的表单下方也添加表单成功消息。
我们将使用带有$success颜色的警告组件来显示我们的成功消息,并将其放置在折叠组件内,以便可以通过垂直过渡显示。为了实现这一点,首先,我们将添加以下标记到我们的表单中,在提交和重置按钮之后以及</form>标签之前,再次以通讯录表单为例:
part-2/chapter-9/website/index.xhtml
<div class="collapse mt-3" id="newsletterConfirmation">
<div class="alert alert-success">
<h3 class="alert-heading h4">Subscribed!</h3>
<p class="mb-0">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Donec mattis posuere consequat.
Nulla fermentum sodales augue, vitae ornare eros
ornare quis. Donec lectus est, congue eu risus quis,
tempus sagittis nunc.</p>
</div>
</div>
在我们的 JavaScript 中,我们现在将更新setTimeout()方法内部使用的代码。我们将从上一个代码块中存储的折叠组件放入一个变量中,并使用该变量通过Collapse()构造函数和show()方法来显示折叠组件。然后,将使用垂直过渡显示警报组件。以新闻通讯表单为例,更新后的 JavaScript 代码如下所示:
part-2/chapter-9/website/js/script.js 行 104-123
// Newsletter form
const newsletterForm = document.querySelector('#newsletterForm');
newsletterForm.addEventListener('submit', function (event) {
if (!newsletterForm.checkValidity()) {
event.preventDefault();
event.stopPropagation();
} else {
event.preventDefault();
const newsletterButton =
document.querySelector('#newsletterButton');
newsletterButton.innerHTML = spinnerMarkup;
newsletterButton.disabled = true;
setTimeout(function() {
const newsletterConfirmationText = 'Subscribed';
newsletterButton.innerHTML =
newsletterConfirmationText;
const newsletterConfirmationElement =
document.querySelector('#newsletterConfirmation');
new bootstrap.Collapse(
newsletterConfirmationElement).show();
}, 2000)
}
newsletterForm.classList.add('was-validated');
}, false)
最后两个代码块以新闻通讯表单为例。联系表单和支付表单的代码类似。
创建程序化标签导航
目前,用户可以使用购物车页面上的标签导航来在三个标签之间导航。我们希望禁用用于标签导航的按钮,而是使用程序化标签导航。这意味着当用户通过每个表单中的提交按钮(分别标记为下一步、下一步和支付)通过结账流程时,活动标签面板将自动更改。
首先,我们需要更新我们的标记以禁用用于标签导航的按钮。对于每个按钮,我们将添加.disabled类以获得正确的样式,并移除data-bs-toggle="tab"属性以禁用点击时更改标签的功能。更新后的标记如下所示:
part-2/chapter-9/website/cart.xhtml
<ul class="nav nav-pills nav-justified mb-5" role="tablist">
<li class="nav-item" role="presentation">
<button type="button" id="cartTabs-1" class="nav-link
active disabled" data-bs-toggle="tab" data-bs-
target="#cartTabs-pane-1" role="tab" aria-
controls="cartTabs-pane-1" aria-selected="true">1\.
Shopping Cart</button>
</li>
<li class="nav-item" role="presentation">
<button type="button" id="cartTabs-2" class="nav-link
disabled" data-bs-toggle="tab" data-bs-
target="#cartTabs-pane-2" role="tab" aria-
controls="cartTabs-pane-2" aria-selected="false">2\.
Shipping Details</button>
</li>
<li class="nav-item" role="presentation">
<button type="button" id="cartTabs-3" class="nav-link
disabled" data-bs-toggle="tab" data-bs-
target="#cartTabs-pane-3" role="tab" aria-
controls="cartTabs-pane-3" aria-selected="false">3\.
Payment Options</button>
</li>
</ul>
在添加用于程序化更改标签的 JavaScript 之前,我们将创建一个辅助函数,用于通过平滑过渡将页面滚动到顶部。该辅助函数由以下代码组成:
part-2/chapter-9/website/js/script.js 行 154-160
// Scroll effect for forms
function scrollToTop() {
scroll({
top: 0,
behavior: "smooth"
});
}
现在我们将看看如何创建用于程序化标签导航的 JavaScript。我们希望从购物车标签面板导航到运输详情标签面板,然后再从运输详情标签面板导航到支付选项标签面板。由于每个标签都需要单独激活,并且我们还需要为购物车和运输详情标签面板中的每个表单提供不同的行为,我们将逐一处理它们。
通过结账流程存储表单值
当我们切换到标签面板时,我们不会在结账流程中存储每个表单的输入值。这必须以使其适用于真实项目的方式完成。
购物车标签面板
在我们的 JavaScript 中,我们将等待表单的submit事件,然后阻止默认的表单提交。之后,我们将调用我们的辅助函数scrollToTop(),并添加一个延迟为600毫秒的setTimeout()方法。这样做是为了让浏览器有足够的时间在执行以下代码之前将页面滚动到顶部。
在setTimeout()方法内部,我们将存储第二个标签的按钮并将其存储在一个变量中,然后使用该变量通过Tab()构造函数和show()方法显示相应的标签页。标签按钮通过data-bs-target属性与相关的标签页相关联:
part-2/chapter-9/website/js/script.js 行 165-177
// Shopping Cart form
const shoppingCartForm = document.querySelector('#shoppingCartForm');
shoppingCartForm.addEventListener('submit', function (event) {
event.preventDefault();
// Go to cart tab 2
scrollToTop();
setTimeout(function() {
const cartTabs2Element =
document.querySelector('#cartTabs-2');
new bootstrap.Tab(cartTabs2Element).show();
}, 600)
}, false)
发货详情标签页
与条件语句的else部分相比,这个表单的不同之处如下:
part-2/chapter-9/website/js/script.js 行 179-198
// Shipping Details form
const shippingForm = document.querySelector('#shippingForm');
shippingForm.addEventListener('submit', function (event) {
if (!shippingForm.checkValidity()) {
event.preventDefault();
event.stopPropagation();
} else {
event.preventDefault();
// Go to cart tab 3
scrollToTop();
setTimeout(function() {
const cartTabs3Element =
document.querySelector('#cartTabs-3');
new bootstrap.Tab(cartTabs3Element).show();
}, 600)
}
shippingForm.classList.add('was-validated');
}, false)
现在我们已经创建了程序化标签导航,可以继续添加一个功能来更新结账流程中的进度状态。
在结账流程中更新进度状态
我们想要改进的最后一个功能是在购物车页面上的结账流程,即当标签页切换时更新进度组件。在购物车标签页中,初始进度应为 0%,当切换到发货详情标签页时,进度应更新为 33%。当发货详情标签页上的表单提交并切换到支付选项标签页时,进度应更新为 67%。最后,当支付选项标签页上的表单提交并显示成功消息后,进度应更新为 100%。
要更新进度组件,我们需要更改.progress-bar元素(进度组件的子元素)的width属性和aria-valuenow属性。aria-valuenow属性的值将直接通过 JavaScript 更新,而width属性的值可以通过内联样式直接更新或通过类间接更新。我们将探讨这两种方法。
使用内联样式更新进度
对于这种方法,首先,我们将使用内联样式更新我们的标记width属性。我们将将其设置为初始值0,这在我们要从一个值过渡到另一个值时是必要的。如果事先不将width设置为0,则.progress-bar元素的宽度将从一个值“跳”到另一个值。以下是更新的代码:
part-2/chapter-9/website/cart.xhtml
<div class="progress mb-4" id="cartProgress">
<div class="progress-bar progress-bar-striped progress-
bar-animated" style="width: 0;" role="progressbar"
aria-valuenow="00" aria-valuemin="0" aria-
valuemax="100"></div>
</div>
在我们的 JavaScript 中,首先,我们将进度组件的.progress-bar元素存储在一个变量中,如下所示:
part-2/chapter-9/website/js/script.js 行 162-163
// Progress component which is animated by the tabs
// navigation below
const cartProgressBar = document.querySelector('#cartProgress .progress-bar');
然后,我们将在购物页面上每个表单的setTimeout()方法末尾添加两行 JavaScript 代码。这将更新内联样式和aria-valuenow属性的值。更新的代码如下,以购物车表单为例:
part-2/chapter-9/website/js/script.js 行 165-177
// Shopping Cart form
const shoppingCartForm = document.querySelector('#shoppingCartForm');
shoppingCartForm.addEventListener('submit', function (event) {
event.preventDefault();
// Go to cart tab 2
scrollToTop();
setTimeout(function() {
const cartTabs2Element =
document.querySelector('#cartTabs-2');
new bootstrap.Tab(cartTabs2Element).show();
cartProgressBar.style.width = "33%";
cartProgressBar.ariaValueNow = 33;
}, 600)
}, false)
我们不会使用内联样式的方法。这是因为我们想要利用宽度实用类.w-33和.w-67,这些是我们使用实用 API 在自定义网站样式时生成的。我们不会使用内联样式。
使用类更新进度
为了使这种方法有效,我们还需要明确指定.progress-element的宽度,以便在添加宽度实用类时能够获得过渡效果。我们可以在我们的标记中保留内联样式,但由于我们想要避免使用内联样式,因此我们将宽度指定在我们的自定义样式表中,如下所示:
part-2/chapter-9/website/scss/_custom-styles.scss 行 17-20
// Set the width of the .progress-bar so we can use the
// transition effect when adding width utility classes
.progress-bar {
width: 0;
}
现在,在我们的 JavaScript 中,我们将添加和移除宽度实用类.w-33、.w-67和.w-100,以实现之前相同的效果。更新aria-valuenow属性的代码将保持不变,并且代码仍然放置在setTimeout()方法的末尾。它将以以下三种不同的形式出现:
part-2/chapter-9/website/js/script.js 行 174-175, 行 192-194, 行 216-218
// Shopping Cart form
cartProgressBar.classList.add("w-33");
cartProgressBar.ariaValueNow = 33;
// Shipping Details form
cartProgressBar.classList.remove("w-33");
cartProgressBar.classList.add("w-67");
cartProgressBar.ariaValueNow = 67;
// Payment Options form
cartProgressBar.classList.remove("w-67");
cartProgressBar.classList.add("w-100");
cartProgressBar.ariaValueNow = 100;
我们想要做的最后一件事是在进度组件达到 100%时停止动画。为了做到这一点,我们只需在从 67%到 100%的过渡完成后从.progress-bar元素中移除.progress-bar-animated类即可。在前一章中,当我们使用 Bootstrap 5 变量自定义网站时,我们使用_default-variable-overrides.scss文件中的$progress-bar-animation-timing变量将.progress-bar元素的动画持续时间设置为 0.5 秒。因此,我们将移除.progress-bar-animated类的代码放在一个延迟为500毫秒的setTimeout()方法中,如下所示:
part-2/chapter-9/website/js/script.js 行 219-221
setTimeout(function() {
cartProgressBar.classList.remove("progress-bar-
animated");
}, 500)
现在我们已经完成了为购物车页面添加交互功能的工作,我们只剩下一个交互功能需要创建。
为产品画廊创建灯箱
我们想要为网站添加的最后一个交互功能是在产品页面上的产品画廊中添加一个灯箱。我们将简单地使用模态组件,当点击其中一个缩略图图像时,显示一个大型图像。
首先,我们将在product.xhtml文件的底部插入模态的最小代码,在</footer>标签之后和两个<script>标签之前。我们将使用.modal-xl和.modal-dialog-centered修饰类使模态框变大并垂直居中。由于我们不希望在模态框中添加任何填充或其他 UI 元素,因此我们不会有任何模态头部、模态主体或模态页脚。我们只想显示我们的大图像以及围绕它的模态背景。仍然可以通过按Escape键或点击背景的任何位置来关闭模态框。<img>标签上的类将被用作 JavaScript 的钩子:
part-2/chapter-9/website/product.xhtml 行 408-414
<div class="modal fade" id="productGallery" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<img class="js-productGalleryImage">
</div>
</div>
</div>
现在,我们需要更新围绕缩略图的链接的标记。将使用一个类作为我们的 JavaScript 的钩子,两个数据属性将用于初始化模态组件,一个数据属性将用于存储我们想在模态中显示的大图的 URL。第一个缩略图图像的更新代码将如下所示:
part-2/chapter-9/website/product.xhtml 行 85
<a href="#" class="js-productGalleryThumbnail" data-bs-toggle="modal" data-bs-target="#productGallery" data-src="img/1600x900.png"><img src="img/185x104.png" class="img-thumbnail" alt="Product image"></a>
在我们的 JavaScript 中,首先,我们将使用我们刚刚添加的类作为钩子,将产品画廊中的所有图像缩略图存储在一个变量中,并使用我们之前提供的类作为钩子将模态中的空图像存储在一个变量中。然后,我们将遍历图像缩略图并监听click事件。在点击事件中,我们将<img>标签的空src属性设置为图像缩略图上定义的data-src属性值。由于此代码将在模态触发时同时执行,因此现在将在模态内部显示大图像。下次点击图像缩略图时,src属性将被替换为data-src属性的新值。此 JavaScript 代码如下所示:
part-2/chapter-9/website/js/script.js 行 231-238
// Handle button click and open product gallery with
// specific "src" value
const productGalleryThumbnails = document.querySelectorAll('.js-productGalleryThumbnail');
const productGalleryImage = document.querySelector('.js-productGalleryImage');
for (let i = 0; i < productGalleryThumbnails.length; i++) {
productGalleryThumbnails[i].addEventListener('click',
function() {
productGalleryImage.src =
productGalleryThumbnails[i].dataset.src;
})
}
现在我们已经为产品画廊创建了自己的灯箱,并且已经完成了向我们的网站添加交互式功能的工作。
摘要
在本章中,我们学习了如何使用 JavaScript 通过交互式功能来改进我们的网站。其中一些功能基于需要自定义 JavaScript 才能工作的 Bootstrap 5 组件,而其他功能则是在不使用 Bootstrap 5 组件的情况下创建的。
在浏览本章的所有场景时,我们看到了如何通过添加这些新的交互式功能使网站更具吸引力和互动性。
本章总结了本书的第二部分,这部分内容主要围绕如何仅使用 Bootstrap 5 创建一个网站,然后通过 Sass 和 JavaScript 对其进行定制和改进。在第三部分,我们将揭示更多使用 Sass 和 CSS 功能与 Bootstrap 5 一起工作的方法,并学习如何优化 Bootstrap 5 代码和文件的使用。
第三部分 – 与 Bootstrap 5 相关的高级主题
在本书的最后部分,我们将学习与 Bootstrap 5 相关的高级主题,这些主题在之前关于定制的部分中尚未涉及。首先,我们将学习可用于各种目的的高级 Sass 和 CSS 功能,然后我们将学习高级 JavaScript 功能,最后,我们将学习如何优化编译后的 Bootstrap 5 CSS 和 JavaScript 代码(包括使用模块打包器)。
本部分包括以下章节:
-
第十章, 使用 Bootstrap 5 的高级 Sass 和 CSS 功能
-
第十一章, 使用 Bootstrap 5 的高级 JavaScript 功能
-
第十二章, 优化 Bootstrap 5 的 CSS 和 JavaScript 代码
第十章:第十章:使用 Bootstrap 5 和高级 Sass 及 CSS 功能
在本章中,我们将探讨与 Bootstrap 5 相关的高级 Sass 和 CSS 功能。在前几章中,我们定制了网站的外观和感觉,但这次我们将主要改变编写代码的方式,而不会影响外观和感觉。此外,我们还将通过一些独立的示例来查看各种其他功能。
我们首先将了解如何使用各种 Bootstrap 5 Sass 混合以不同的方式编写代码,之后,我们将看到一些 Bootstrap 5 Sass 函数的示例。
然后,我们将看到如何利用 Sass 的扩展功能来处理语义化 HTML 并创建自定义组件。
之后,我们将了解创建自定义组件的最佳和推荐方法,使用 Bootstrap 5 变量、混合和函数。
在本章的末尾,我们将看到如何利用 Bootstrap 5 带来的 CSS 自定义属性来创建深色主题,并定制组件和辅助工具。
最后,我们将探讨 Bootstrap 的侧项目 RFS,并学习如何使用它来计算自动响应式 CSS 值。
在本章中,我们将涵盖以下主要主题:
-
使用 Bootstrap 5 Sass 混合
-
使用 Bootstrap 5 Sass 函数
-
扩展 Bootstrap 5 类以实现语义化 HTML
-
扩展 Bootstrap 5 类以创建自定义组件
-
使用 Bootstrap 5 变量、混合和函数创建自定义组件
-
使用 Bootstrap 5 CSS 自定义属性
-
使用 RFS Sass 插件
如前所述,对于这些主题中的某些,我们将更新网站的部分代码,而对于其他主题,我们只会看到与该主题相关的独立示例。
技术要求
-
为了预览这些示例,您需要一个代码编辑器和浏览器。所有代码示例的源代码都可以在这里找到:
github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide -
要将 Sass 编译为 CSS,您需要以下之一:
-
Node.js,如果您更喜欢使用终端(Mac)或命令提示符(Windows)的命令行界面(CLI)
-
Scout-App,如果您更喜欢图形用户界面(GUI)
-
Visual Studio Code,如果您更喜欢使用 Visual Studio Code 市场上的扩展
-
所有这些方法都在第二章**,使用和编译 Sass中进行了解释。
使用 Bootstrap 5 Sass 混合
Bootstrap 5 包含许多 Sass 混合。其中一些被 Bootstrap 5 的其他部分使用,而少数则没有。所有这些都可以在您的 Sass 代码中使用。在本节中,我们将首先概述 Bootstrap 5 中包含的各种混合,它们的作用以及它们如何与其他 Bootstrap 5 代码相关。然后,我们将看到如何使用这些混合的一些不同示例。
混合概述
在mixins文件夹中,我们总共有 25 个文件,这些都是 Sass 部分。以下是这些文件的概述,包括关于 Bootstrap 5 中哪些元素(组件、助手或其他)使用了这些混入(如果有的话)的注释:
bootstrap/scss/mixins
_alert.scss // Alerts
_backdrop.scss // Modal, Offcanvas
_border-radius.scss // Used by many
_box-shadow.scss // Used by many
_breakpoints.scss // Used by many
_buttons.scss // Buttons
_caret.scss // Dropdowns
_clearfix.scss // Carousel, Clearfix
_color-scheme.scss // Not used
_container.scss // Container
_deprecate.scss // Not used
_forms.scss // Validation
_gradients.scss // 1 used by many, 7 not being used
_grid.scss // Grid
_image.scss // Images
_list-group.scss // List group
_lists.scss // Typography, Pagination
_pagination.scss // Pagination
_reset-text.scss // Popovers, Tooltips
_resize.scss // Not used
_table-variants.scss // Tables
_text-truncate.scss // Text truncation
_transition.scss // Used by many
_utilities.scss // Utility API
_visually-hidden.scss // Visually hidden
现在,我们将看到如何根据它们的用法以三种不同的方式将这些混入分组。
依赖于全局选项的混入
一些混入(mixins)依赖于我们在第四章中学习到的全局选项,即 Bootstrap 5 全局选项和颜色。因此,只有当特定选项被启用时,这些混入才会返回代码:
_border-radius.scss: @mixin border-radius
_box-shadow.scss: @mixin box-shadow
_caret.scss: @mixin caret
_deprecate.scss: @mixin deprecate
_forms.scss: @mixin form-validation-state
_gradients.scss: @mixin gradient-bg
_transition.scss: @mixin transition
未使用的混入
一些混入实际上没有被其他 Bootstrap 5 代码使用。我们将在本节稍后看到一些这些混入的用途:
_color-scheme.scss: @mixin color-scheme
_gradients.scss: @mixin gradient-x, @mixin gradient-y, @mixin gradient-directional, @mixin gradient-x-three-colors, @mixin gradient-y-three-colors, and @mixin gradient-radial
_resize.scss: @mixin resizable
用于变体的混入
一些混入用于创建 Bootstrap 5 组件的不同变体。这可能是针对上下文颜色、大小和断点特定行为的变体:
_alert.scss: @mixin alert-variant
_buttons.scss: @mixin button-variant, @mixin button-outline-variant, and @mixin button-size
_list-group.scss: @mixin list-group-item-variant
_pagination.scss: @mixin pagination-size
_table-variants.scss: @mixin table-variant
示例
我们现在将看到一些示例,展示我们如何在我们的代码中使用一些混入。我们不会使用这些混入更新我们的网站,而是查看一些独立的示例。
响应式网格系统
在本例中,我们将创建一个响应式网格系统,包括一个容器,使用各种混入。
对于此示例,我们使用了以下仅使用默认 HTML 元素且不包含类的语义 HTML:
part-3/chapter-10/examples/mixins/responsive-grid-system/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>Container and Grid Mixins</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>Header</header>
<main>
<nav>Nav</nav>
<article>Article</article>
<aside>Aside</aside>
</main>
<footer>Footer</footer>
</body>
</html>
现在,我们首先将一个容器添加到<body>元素中。当使用混入时,它将创建一个流体容器,这就是我们在示例中将使用的。它需要一些额外的自定义代码来创建与默认.container类在不同断点上的不同max-width实例相同的行为。
在添加容器后,我们将使用<main>元素作为行和<nav>、<article>和<aside>元素作为列创建一个简单的响应式网格。我们不会向<header>和<footer>添加任何混入。
此示例所需的 Sass 代码如下:
part-3/chapter-10/examples/mixins/responsive-grid-system/scss/style.scss
// Bootstrap 5
@import "../../../../../../bootstrap/scss/bootstrap.scss";
body {
@include make-container();
}
main {
@include make-row();
}
nav {
@include make-col-ready();
@include media-breakpoint-up(lg) {
@include make-col(3);
}
}
article {
@include make-col-ready();
@include media-breakpoint-up(lg) {
@include make-col(6);
}
}
aside {
@include make-col-ready();
@include media-breakpoint-up(lg) {
@include make-col(3);
}
}
当这个示例在浏览器中查看时,我们将看到页面的布局现在正在使用一个容器和一个响应式网格系统。
断点媒体查询
在此示例中,我们将更详细地查看用于断点的媒体查询混入。在_breakpoints.scss文件中,我们将找到四个混入和四个函数,其中三个函数主要被这些混入使用,一个函数breakpoint-infix()被其他文件中的各种组件使用。现在,我们将专注于混入。
以下是各种断点媒体查询混入的概述,以及它们所做简短描述:
media-breakpoint-up($name, $breakpoints: $grid-breakpoints)
-
对于具有最小断点宽度的视口大小
-
由
$name参数指定的断点 -
传递给混入的内容块将被应用于指定的断点宽度及其更宽的范围
-
对于最小的断点没有媒体查询
media-breakpoint-down($name, $breakpoints: $grid-breakpoints)
-
对于最大断点宽度的视口大小
-
由
$name参数指定的断点 -
传递给混入函数的内容块将应用于指定的断点宽度和更窄的宽度
media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints)
-
对于跨越多个断点宽度的视口大小
-
由
$lower和$upper参数指定的断点 -
传递给混入函数的内容块将应用于指定的下限和上限断点宽度之间
media-breakpoint-only($name, $breakpoints: $grid-breakpoints)
-
对于介于最小和最大断点宽度之间的视口大小
-
由
$name参数指定的断点 -
传递给混入函数的内容块将仅在指定的断点最小和最大宽度之间应用
$breakpoints 参数是一个可选参数,默认值为 $grid-breakpoints。这意味着它将使用 $grid-breakpoints 映射中定义的断点宽度。
要查看这些混入函数的实际效果,这里有一个示例,它最初隐藏一些元素,然后使用不同的混入函数显示它们。首先,这是示例的 HTML 代码,我们使用了 .up、.down、.between 和 .only 类,这些类将作为我们的 Sass 中的选择器使用:
part-3/chapter-10/examples/mixins/media-queries-for-breakpoints/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>Media queries for breakpoints</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body class="p-4">
<div class="up">@include media-breakpoint-up(lg):
Visible on breakpoint sizes lg, xl and xxl</div>
<div class="down">@include media-breakpoint-down(md):
Visible on breakpoint sizes xs and sm</div>
<div class="between">@include media-breakpoint-
between(md, xl): Visible on breakpoint size md and
lg</div>
<div class="only">@include media-breakpoint-only(sm):
Visible on breakpoint size sm</div>
</body>
</html>
以下是 Sass 代码,其中我们最初隐藏所有元素,然后使用各种混入函数显示它们:
part-3/chapter-10/examples/mixins/media-queries-for-breakpoints/scss/style.scss
// Bootstrap 5
@import "../../../../../../bootstrap/scss/bootstrap.scss";
.up {
display: none;
@include media-breakpoint-up(lg) {
display: block;
};
}
.down {
display: none;
@include media-breakpoint-down(md) {
display: block;
};
}
.between {
display: none;
@include media-breakpoint-between(md, xl) {
display: block;
};
}
.only {
display: none;
@include media-breakpoint-only(sm) {
display: block;
};
}
如果你在一个浏览器中查看这个示例并调整窗口大小,你会看到 <div> 元素仅在特定的断点可见。
辅助函数
在此示例中,我们将使用两个辅助混入函数。我们将使用视觉隐藏混入函数用于标题元素,以及文本截断混入函数用于段落元素。此示例的 HTML 代码如下:
part-3/chapter-10/examples/mixins/helpers/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>Helper Mixins</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Title for screen readers</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Duis convallis velit quis sapien sollicitudin
ultrices. Ut metus tortor, aliquet non rutrum ac,
dapibus vehicula augue. Etiam congue erat sem, vitae
gravida nunc pretium vitae. Fusce sed ex tellus.
Quisque auctor viverra feugiat. Nulla urna odio,
porta ut tristique ut, consequat non dolor. Etiam
varius maximus dolor, at consectetur lectus. Mauris
rutrum aliquet tellus, sed convallis diam.</p>
</body>
</html>
用于此示例的 Sass 代码如下所示:
part-3/chapter-10/examples/mixins/helpers/scss/style.scss
// Bootstrap 5
@import "../../../../../../bootstrap/scss/bootstrap.scss";
h1 {
@include visually-hidden();
}
p {
@include text-truncate();
}
当这个示例在浏览器中查看时,标题元素现在将不会在屏幕上显示,但对屏幕阅读器可见,而段落将只有一行文本,文本在末尾被截断,后面跟着省略号。
深色主题
在此示例中,我们将看到如何使用颜色方案混入函数定义深色主题(也称为暗模式)。当用户在浏览器或操作系统中开启 暗模式 浏览时,混入函数是有效的。颜色方案混入函数目前在 Bootstrap 5 中尚未使用,但仍然提供给我们使用。在 Bootstrap 5 的下一个小版本 v5.3.0 中,Bootstrap 将支持 暗模式,届时混入函数可能会在 Sass 代码的各个元素中使用。在此之前,我们将为 暗模式 创建自己的深色主题。
混入函数的源代码如下所示:
bootstrap/scss/mixins/_color-scheme.scss
@mixin color-scheme($name) {
@media (prefers-color-scheme: #{$name}) {
@content;
}
}
如您所见,我们向混入传递了颜色主题的名称(在这种情况下是dark),然后是它内部的全部 CSS 规则。然后,这些规则被放置在一个媒体查询中,名称被用作媒体特性prefers-color-scheme: #{$name}的值。
现在,我们将使用混入为我们的网站创建一个深色主题。在混入内部,我们将添加各种 CSS 规则以针对我们想要颜色变化的元素。基本上,我们希望亮色变暗,暗色变亮。我们的代码如下所示:
part-3/chapter-10/website/scss/_custom-styles.scss 行 22-51
// Dark color theme
@include color-scheme(dark) {
// Body color
body {
background-color: $dark;
color: $light;
}
// Color utilities
.bg-light {
background-color: $dark !important;
}
.bg-dark {
background-color: $gray-700 !important;
}
// Components
.accordion-button,
.accordion-item,
.card,
.list-group-item {
background-color: $dark;
}
.accordion-button,
.breadcrumb-item.active,
.figure-caption,
.list-group-item,
.navbar-light .navbar-brand,
.navbar-light .navbar-nav .nav-link {
color: $light;
}
}
如前述代码所示,我们首先为<body>元素定义了一些基础颜色。然后,我们使用!important规则覆盖了亮色和暗色的背景颜色工具,因为默认情况下工具类具有!important规则。最后,我们覆盖了具有亮色背景或暗色文字颜色的组件。
深色主题在浏览器中查看我们更新的网站(本章代码中的website文件夹)时可以清晰地看到所有细节,以下是主页的截图:
.jpg)
.jpg)
图 10.1 – 带有深色主题的网站主页
您可能想尝试其他亮色和暗色来为深色主题进行实验,但这是使用的方法。
渐变
在本例中,我们将看到如何使用各种渐变混入。根据具体的渐变混入,可以指定各种参数,包括颜色、程度、角度和停止点。在我们的例子中,我们将仅使用默认混入参数和一些颜色工具,以便更好地查看这些渐变。
在本例的 HTML 中,我们有一些添加了大小和颜色工具的<div>元素。请注意,我们已将背景颜色添加到第一个和最后一个示例中,因为那些渐变默认是白色的。我们还添加了混入的名称作为类和<div>元素的文本,这个类将在我们的 Sass 代码中使用。首先,这是 HTML 代码:
part-3/chapter-10/examples/mixins/gradients/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>Gradient Mixins</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="p-5 text-light bg-dark gradient-
bg">gradient-bg</div>
<div class="p-5 text-light gradient-x">gradient-x</div>
<div class="p-5 text-light gradient-y">gradient-y</div>
<div class="p-5 text-light gradient-
directional">gradient-directional</div>
<div class="p-5 text-light gradient-x-three-
colors">gradient-x-three-colors</div>
<div class="p-5 text-light gradient-y-three-
colors">gradient-y-three-colors</div>
<div class="p-5 text-light gradient-radial">gradient-
radial</div>
<div class="p-5 text-light bg-dark gradient-
striped">gradient-striped</div>
</body>
</html>
在我们的 Sass 代码中,我们首先将全局选项$enable-gradients设置为true,这是使用gradient-bg混入所必需的。另外,也可以在元素上使用.bg-gradient类而不需要启用渐变的全局选项。但鉴于本节是关于使用混入,我们将使用这个渐变的混入版本。
启用渐变的全局选项后,我们将在 Sass 代码中使用前面提到的类作为 CSS 选择器,并包含各种渐变混入:
part-3/chapter-10/examples/mixins/gradients/scss/style.scss
// Bootstrap 5
$enable-gradients: true;
@import "../../../../../../bootstrap/scss/bootstrap.scss";
.gradient-bg {
@include gradient-bg();
}
.gradient-x {
@include gradient-x();
}
.gradient-y {
@include gradient-y();
}
.gradient-directional {
@include gradient-directional();
}
.gradient-x-three-colors {
@include gradient-x-three-colors();
}
.gradient-y-three-colors {
@include gradient-y-three-colors();
}
.gradient-radial {
@include gradient-radial();
}
.gradient-striped {
@include gradient-striped();
}
各种渐变看起来是这样的:

图 10.2 – 所有渐变混入示例
使用 Bootstrap 5 Sass 函数
Bootstrap 5 包含各种 Sass 函数,其中大多数都放在_functions.scss文件中。其中一些函数用于评估源代码或操作 Sass 映射,但在这个部分,我们将关注更有用的颜色函数。Bootstrap 5 中有多个不同的颜色函数,现在我们将看到如何在我们自己的 Sass 代码中使用其中的一些示例。我们不会在我们的网站上使用这些函数,而是查看一些独立的示例。
着色颜色
tint-color()函数通过使用 Sass 的颜色混合函数将颜色与白色混合来增加颜色的亮度。你指定$color以及你想要它变亮多少,定义为$weight。
函数的代码如下:
bootstrap/scss/_functions.scss 行 205-208
@function tint-color($color, $weight) {
@return mix(white, $color, $weight);
}
以下是如何将$primary颜色着色25%的示例:
part-3/chapter-10/examples/functions/scss/style.scss 行 4-6
.bg-primary-tinted {
background-color: tint-color($primary, 25%);
}
生成的 CSS 将如下所示:
part-3/chapter-10/examples/functions/css/style.css
.bg-primary-tinted {
background-color: #4a92fe;
}
在这里,你可以看到在浏览器中的效果,它与$primary颜色一起显示:

图 10.3 – 使用主颜色着色颜色函数的示例
阴影颜色
shade-color()函数通过使用 Sass 的颜色混合函数将颜色与黑色混合来增加颜色的暗度。你指定$color以及你想要它变暗多少,定义为$weight。
函数的代码如下:
bootstrap/scss/_functions.scss 行 210-213
@function shade-color($color, $weight) {
@return mix(black, $color, $weight);
}
以下是如何将$primary颜色阴影25%的示例:
part-3/chapter-10/examples/functions/scss/style.scss 行 7-9
.bg-primary-shaded {
background-color: shade-color($primary, 25%);
}
生成的 CSS 将如下所示:
part-3/chapter-10/examples/functions/css/style.css
.bg-primary-shaded {
background-color: #0a53be;
}
在这里,你可以看到在浏览器中的效果,它与$primary颜色一起显示:

图 10.4 – 使用主颜色阴影颜色函数的示例
调整颜色
shift-color()函数是着色和阴影颜色函数的组合。如果$weight为正,则$color将被阴影化,否则将被着色。
函数的代码如下:
bootstrap/scss/_functions.scss 行 215-218
@function shift-color($color, $weight) {
@return if($weight > 0, shade-color($color, $weight),
tint-color($color, -$weight));
}
以下是如何将$primary颜色分别调整25%和-25%的示例:
part-3/chapter-10/examples/functions/scss/style.scss 行 10-15
.bg-primary-shifted-positive {
background-color: shift-color($primary, 25%);
}
.bg-primary-shifted-negative {
background-color: shift-color($primary, -25%);
}
生成的 CSS 将如下所示:
part-3/chapter-10/examples/functions/css/style.css
.bg-primary-shifted-positive {
background-color: #0a53be;
}
.bg-primary-shifted-negative {
background-color: #4a92fe;
}
在这里,你可以看到在浏览器中的效果,它与$primary颜色一起显示:

图 10.5 – 使用主色调的 shift-color 函数示例
颜色对比度
color-contrast() 函数根据指定的基本颜色(默认情况下为 $black 或 $white 颜色)返回一个对比色,考虑到可访问性标准。这在遍历颜色映射时很有用,其中你想要确保,例如,文本颜色与映射中指定的背景颜色具有正确的颜色对比度比率。我们现在想看看我们如何做到这一点:为 $theme-colors 映射中的每个颜色生成一个对比色。以下是我们将使用以生成类的 Sass 代码,使用映射中颜色的名称,并以前缀 .contrast-color- 开头:
part-3/chapter-10/examples/functions/scss/style.scss 行 17-21
@each $color, $value in $theme-colors {
.contrast-color-#{$color} {
color: color-contrast($value);
}
}
这将生成以下 CSS:
part-3/chapter-10/examples/functions/css/style.css
.contrast-color-primary { color: #fff; }
.contrast-color-secondary { color: #fff; }
.contrast-color-success { color: #fff; }
.contrast-color-info { color: #000; }
.contrast-color-warning { color: #000; }
.contrast-color-danger { color: #fff; }
.contrast-color-light { color: #000; }
.contrast-color-dark { color: #fff; }
在 CSS 中,我们可以看到当使用 color-contrast() 函数时,在 $theme-colors 映射中为每个颜色选择了对比色 #fff(白色)或 #000(黑色),以确保足够的颜色对比度比率。
在这里,你可以看到它在浏览器中的样子:

图 10.6 – 使用主题颜色的 color-contrast 函数示例
我们已经看到了如何使用一些 Bootstrap 5 的颜色函数与 Sass。接下来,我们将看看如何为语义 HTML 扩展 Bootstrap 5 类。
为语义 HTML 扩展 Bootstrap 5 类
当使用 Bootstrap 5 时,你可能会在你的标记中添加很多类,这会使你在将来想要替换 Bootstrap 5 样式时很难。相反,你可以选择只使用语义 HTML 元素,同时仍然使用 Bootstrap 5 样式。你的 HTML 可以没有任何类,或者只有你选择的类(以及这些类的命名)。因此,HTML 的结构和(可选)类可以是任何你想要的。
为了理解为什么这可能是有吸引力的,我们将考虑 Bootstrap 5 CSS 规则集为两件不同的事情:
-
一组样式规则(CSS 声明块)
-
这些样式规则的词汇(选择器)
我们希望获得样式规则的好处,但不想依赖于其词汇,即特定的 Bootstrap 5 类。我们可以通过在我们的页面上使用语义 HTML 并用 Sass 扩展 Bootstrap 5 类来代替直接在标记中使用它们来实现这一点。
将这种方法应用于我们网站上的所有 HTML 是一项艰巨的任务,所以我们只是简单地看看这个例子是如何工作的。
考虑这个使用 Bootstrap 5 类以常规方式创建的简单布局:
part-3/chapter-10/examples/semantic-extend/default/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>Semantic Extending</title>
<link rel="stylesheet" href="../../../../../
bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1 class="display-1 text-center">Heading</h1>
<p class="lead">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis convallis velit
quis sapien sollicitudin ultrices.</p>
<div class="row">
<nav class="col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item list-group-
item-action">List group item one</a>
<a href="#" class="list-group-item list-group-
item-action">List group item two</a>
<a href="#" class="list-group-item list-group-
item-action">List group item three</a>
</div>
</nav>
<article class="col-lg-6">
<h2 class="display-6">Article Heading</h2>
<p>Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Duis convallis velit quis
sapien sollicitudin ultrices. Ut metus tortor,
aliquet non rutrum ac, dapibus vehicula augue.
Etiam congue erat sem, vitae gravida nunc
pretium vitae. Fusce sed ex tellus. Quisque
auctor viverra feugiat. Nulla urna odio,
porta ut tristique ut, consequat non dolor.
Etiam varius maximus dolor, at consectetur
lectus. Mauris rutrum aliquet tellus, sed
convallis diam.</p>
</article>
<aside class="col-lg-3">
<div class="card">
<div class="card-body">
<a href="#" class="btn btn-primary">Contact
support</a>
</div>
</div>
</aside>
</div>
<footer>
<ul class="list-inline text-center">
<li class="list-inline-item"><a href="#">Footer
link one</a></li>
<li class="list-inline-item"><a href="#">Footer
link two</a></li>
<li class="list-inline-item"><a href="#">Footer
link three</a></li>
</ul>
</footer>
</div>
</body>
</html>
现在,我们将移除所有 Bootstrap 5 类,并仅依赖于语义 HTML 元素:
part-3/chapter-10/examples/semantic-extend/extended-classes/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>Semantic Extending</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Heading</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Duis convallis velit quis sapien
sollicitudin ultrices.</p>
</header>
<main>
<nav>
<div>
<a href="#">List group item one</a>
<a href="#">List group item two</a>
<a href="#">List group item three</a>
</div>
</nav>
<article>
<h2>Article Heading</h2>
<p>Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Duis convallis velit quis
sapien sollicitudin ultrices. Ut metus tortor,
aliquet non rutrum ac, dapibus vehicula augue.
Etiam congue erat sem, vitae gravida nunc
pretium vitae. Fusce sed ex tellus. Quisque
auctor viverra feugiat. Nulla urna odio, porta
ut tristique ut, consequat non dolor. Etiam
varius maximus dolor, at consectetur lectus.
Mauris rutrum aliquet tellus, sed convallis
diam.</p>
</article>
<aside>
<div>
<div>
<a href="#">Contact support</a>
</div>
</div>
</aside>
</main>
<footer>
<ul>
<li><a href="#">Footer link one</a></li>
<li><a href="#">Footer link two</a></li>
<li><a href="#">Footer link three</a></li>
</ul>
</footer>
</body>
</html>
现在我们的标记中没有 Bootstrap 5 的证据。为了仍然从 Bootstrap 5 的样式中获得好处,我们需要使用 Sass 的@extend规则扩展 Bootstrap 5 类,如下所示:
part-3/chapter-10/examples/semantic-extend/extended-classes/scss/style.scss
// Bootstrap 5
@import "../../../../../../bootstrap/scss/bootstrap.scss";
body {
@extend .container;
}
header {
h1 {
@extend .display-1, .text-center;
}
p {
@extend .lead;
}
}
main {
@extend .row;
> nav {
@extend .col-lg-3;
> div {
@extend .list-group;
a {
@extend .list-group-item, .list-group-item-action;
}
}
}
> article {
@extend .col-lg-6;
h2 {
@extend .display-6;
}
}
> aside {
@extend .col-lg-3;
> div {
@extend .card;
> div {
@extend .card-body;
> a {
@extend .btn, .btn-primary;
}
}
}
}
}
footer {
> ul {
@extend .list-inline, .text-center;
> li {
@extend .list-inline-item;
}
}
}
现在,我们将在浏览器中看到相同的视觉结果。标记已经更改,但视觉风格保持不变。
带有 Bootstrap 5 的语义 HTML
应该注意的是,完全有可能将语义 HTML 元素与 Bootstrap 5 类一起使用,因为这些类可以用于任何你想要的 HTML 元素。本节中描述的方法旨在与没有类或仅使用我们想要的类(以及这些类的命名)的语义 HTML 一起使用。
扩展 Bootstrap 5 类以创建自定义组件
在本节中,我们将看到如何使用 Sass 的@extend规则扩展现有的 Bootstrap 5 类。使用这种方法,将有可能创建相同的 UI 元素,但 HTML 代码更少,这对可读性更好。
我们将在我们的网站中的三个 UI 元素上使用此方法:页面标题全局模块、产品页面中的评论部分的 blockquote,以及购物车页面摘要部分的底部边框。
页面标题全局模块
页面标题全局模块用于所有页面,除了主页和产品页面。此模块的视觉风格类似于在 Bootstrap 的早期版本中找到的 jumbotron 组件。现在,我们将扩展页面标题全局模块使用的 Bootstrap 5 类,以使标记更简单。我们将为此自定义组件使用名称jumbotron。
在我们新自定义组件的 HTML 中,我们必须保留一个父元素(.jumbotron),这样我们就可以给组件一个覆盖全宽的背景色,然后通过扩展.container类来限制实际内容在子元素(.jumbotron-heading)内:
part-3/chapter-10/website/shop.xhtml 行 67-69
// Original code
<div class="bg-light py-5 mb-5">
<div class="container">
<h1 class="display-1 text-center mb-0">Shop</h1>
</div>
</div>
// Updated code
<div class="jumbotron">
<h1 class="jumbotron-heading">Shop</h1>
</div>
在我们的样式表中,我们现在可以扩展所有类,如下所示:
part-3/chapter-10/website/scss/_custom-styles.scss 行 53-59
// Create a custom jumbotron component that extends various
// Bootstrap 5 classes
.jumbotron {
@extend .bg-light, .py-5, .mb-5;
}
.jumbotron-heading {
@extend .container, .display-1, .text-center, .mb-0;
}
评论部分的 Blockquote
在此自定义组件的quote中。
在我们新自定义组件的 HTML 中,我们本可以仅扩展图标使用的类,并保留父.blockquote类。但我们要将其作为一个默认的 blockquote 元素的替代组件,这就是为什么我们还将扩展父.blockquote类,这样我们就可以给它一个新的名称:
part-3/chapter-10/website/product.xhtml 行 307-310
// Original code
<blockquote class="blockquote">
<div class="text-secondary float-start fs-1 lh-1 mt-1
me-2 border-top border-start border-2 border-secondary
p-1"><i class="bi-quote"></i></div>
<p>[Text]</p>
</blockquote>
// Updated code
<blockquote class="quote">
<div class="quote-icon"><i class="bi-quote"></i></div>
<p>[Text]</p>
</blockquote>
在我们的样式表中,我们现在可以扩展所有类,如下所示:
part-3/chapter-10/website/scss/_custom-styles.scss 行 61-67
// Create a custom quote component that extends various Bootstrap 5 classes
.quote {
@extend .blockquote;
}
.quote-icon {
@extend .text-secondary, .float-start, .fs-1, .lh-1,
.mt-1, .me-2, .border-top, .border-start, .border-2,
.border-secondary, .p-1;
}
摘要部分的边框
在这个自定义组件的 summary-border 中。
更新后的 HTML 代码如下所示:
part-3/chapter-10/website/cart.xhtml 行 271
// Original code
<div class="border-bottom border-2 border-light mb-4 pb-4 border-bottom-md-0 border-end-md border-md-2 pb-md-0 mb-md-0 border-bottom-xl border-end-xl-0 border-xl-2 pb-xl-4 mb-xl-4">
</blockquote>
// Updated code
<div class="summary-border">[Summary section code]</div>
在我们的样式表中,我们现在可以像这样扩展所有类:
part-3/chapter-10/website/scss/_custom-styles.scss 行 69-72
// Create a custom summary border component that extends border and spacing utilities
.summary-border {
@extend .border-bottom, .border-2, .border-light, .mb-4,
.pb-4, .border-bottom-md-0, .border-end-md, .border-md-
2, .pb-md-0, .mb-md-0, .border-bottom-xl, .border-end-
xl-0, .border-xl-2, .pb-xl-4, .mb-xl-4, .border-bottom,
.border-2, .border-light, .mb-4, .pb-4, .border-
bottom-md-0, .border-end-md, .border-md-2, .pb-md-0,
.mb-md-0, .border-bottom-xl, .border-end-xl-0, .border-
xl-2, .pb-xl-4, .mb-xl-4;
}
关于 @extend 规则的重要说明
Sass 的 @extend 规则越来越不受欢迎,许多人建议不要使用它。原因是它会改变源顺序并创建不想要的 CSS 组合。尽管它可能会减少 CSS 文件的大小,但它可能会对网络性能产生不利影响。这个讨论很快就会变得技术性和冗长,所以如果你想了解更多,我鼓励你谷歌搜索“Sass extend performance”或类似的内容。Sass 的 @placeholder 和 @mixin 规则可能更适合实现相同的功能,但当你不希望更改源代码(正如本书前面所解释的,在使用 Bootstrap 5 时我们不希望这样做)时,这里描述的方法是可行的。
我们现在已经学会了如何使用 Sass 的 @extend 规则扩展 Bootstrap 5 类来创建自定义组件。接下来,我们将看到如何使用 Bootstrap 5 变量、混合和函数以另一种方式创建自定义组件。
使用 Bootstrap 5 变量、混合和函数创建自定义组件
在上一节中,我们看到了如何使用 Sass 的 @extend 规则扩展现有的 Bootstrap 5 类来创建自定义组件。在本节中,我们将看到如何使用 Bootstrap 团队推荐的方法使用 Sass 创建自定义组件。这种方法首先涉及尽可能多地重用 Bootstrap 变量、混合和函数,以便自定义组件会受到全局选项和 Bootstrap 变量的任何自定义的影响。其次,组件将基于一个基类,该基类尽可能多地组合共享属性,然后是一系列修饰类,这些修饰类将单独的样式组合在一起。
我们将要创建的自定义组件是一个时序组件,它看起来像这样:

图 10.7 – 定制的时序组件
在屏幕截图中,我们看到正在使用基类,但我们还将创建用于上下文颜色变体和响应式水平变体的修饰类。对于时序组件,我们使用一个无序列表,其中包含多个列表项。我们使用类 .timeline 作为父元素,使用类 .timeline-item 作为内部的列表项。在每个列表项内部,我们有一个具有类 .timeline-time 的元素用于每个事件的时刻,以及一个具有类 .timeline-text 的段落用于每个事件的描述。
这个自定义组件的 HTML 代码如下所示:
part-3/chapter-10/examples/custom-component/index.xhtml
<ul class="timeline">
<li class="timeline-item">
<div class="timeline-time">2022</div>
<p class="timeline-text">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis convallis velit
quis sapien sollicitudin ultrices.</p>
</li>
[More timeline items here]
</ul>
在我们的 Sass 代码中,我们首先导入 Bootstrap 5 文件,然后尽可能多地使用 Bootstrap 5 变量和混入定义 CSS 规则,这样我们的组件就会受到我们在 Sass 代码中可能使用的任何自定义的影响。我们使用 Bootstrap 5 变量进行间距、边框、颜色和字体粗细,并使用混入创建无样式的列表,并在全局阴影选项 ($enable-shadows) 启用时添加阴影。
我们自定义组件的 Sass 代码如下:
part-3/chapter-10/examples/custom-component/scss/style.scss 行 1-40
// Bootstrap 5
@import "../../../../../bootstrap/scss/bootstrap.scss";
.timeline {
@include list-unstyled;
margin: $spacer 0;
}
.timeline-item {
padding-bottom: $spacer;
border-left: $border-width solid $border-color;
position: relative;
padding-left: $spacer;
margin-left: .625rem;
&:last-child{
border: 0;
padding-bottom: 0;
}
&::before {
content: '';
width: 1.2rem;
height: 1.2rem;
background: $white;
border: $border-width solid $border-color;
@include box-shadow($box-shadow-inset);
border-radius: 50%;
position: absolute;
left: -.6rem;
top: 0;
}
}
.timeline-time {
font-weight: $font-weight-bold;
top: -0.1875rem;
position: relative;
}
.timeline-text {
margin-bottom: 0;
}
创建上下文颜色变体
现在,我们将为我们的组件创建上下文颜色变体。我们希望组件能够有一系列修饰类,可以添加到单个时间轴项中,这样就会设置以下三个项目的颜色:
-
.timeline-time元素的文本颜色 -
.timeline-item元素的边框颜色 -
.timeline-item元素的::before伪元素的边框颜色
为了生成上下文颜色变体的各种修饰类,我们将使用 Sass 循环遍历 $theme-colors 映射。在循环中,键被分配给 $state 变量,值被分配给 $value 变量。然后使用 $state 变量生成各种类,而 $value 变量用于将颜色添加到不同的元素中。
Sass 代码看起来是这样的:
part-3/chapter-10/examples/custom-component/scss/style.scss 行 42-54
@each $state, $value in $theme-colors {
.timeline-item-#{$state} {
border-color: $value;
&::before {
border-color: $value;
}
.timeline-time {
color: $value;
}
}
}
使用这种方法,我们将为每个主题颜色生成修饰类,例如,例如,为 $primary 颜色生成 .timeline-item-primary 修饰类。然后,这些修饰类将以以下方式添加到我们的 HTML 中:
part-3/chapter-10/examples/custom-component/index.xhtml
<ul class="timeline">
<li class="timeline-item timeline-item-primary
">
<div class="timeline-time">2022</div>
<p class="timeline-text">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis convallis velit
quis sapien sollicitudin ultrices.</p>
</li>
[More timeline items here]
</ul>
下面是不同上下文颜色变体的截图:

图 10.8 – 带有上下文颜色变体的自定义时间轴组件
创建响应式水平变体
现在,我们将为我们的组件创建响应式水平变体。我们希望组件能够有一系列修饰类,可以添加到父元素中,这样就会定义在什么断点下组件将在水平版本中显示。
下面是水平版本的截图:

图 10.9 – 水平版本的自定义时间轴组件
为了生成响应式水平变体的各种修饰类,我们将使用 Sass 循环遍历 $grid-breakpoints 映射。在那个循环中,键被分配给 $breakpoint 变量,然后首先用作 media-breakpoint-up() 混合函数的参数。在媒体查询内部,$breakpoint 变量用作 breakpoint-infix() 函数的参数以生成 $infix 变量的值,然后使用该值生成具有正确断点后缀(-sm、-md、-lg、-xl 或 -xxl)的各种类名。
Sass 代码如下所示:
part-3/chapter-10/examples/custom-component/scss/style.scss 行 56-75
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-
breakpoints);
.timeline-horizontal#{$infix} {
display: flex;
padding-top: 0.6rem;
overflow-y: scroll;
.timeline-item {
border-left: none;
border-top: $border-width solid $border-color;
&::before {
top: -0.6rem;
}
}
}
}
}
使用此方法,我们将为每个断点生成修饰类,例如,例如,为 sm 断点生成 .timeline-horizontal-sm 修饰类。请注意,我们还将生成 .timeline-horizontal 修饰类,该类将在所有屏幕尺寸下显示组件的水平版本。
修饰类可以通过以下方式添加到我们的 HTML 中:
part-3/chapter-10/examples/custom-component/index.xhtml
<ul class="timeline timeline-horizontal-sm">
<li class="timeline-item">
<div class="timeline-time">2022</div>
<p class="timeline-text">Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis convallis velit
quis sapien sollicitudin ultrices.</p>
</li>
[More timeline items here]
</ul>
在浏览器中查看此示例时,您可以看到不同的时间线组件如何在不同的断点处转换为水平版本。
在本节中,我们看到了如何使用 Bootstrap 背后团队推荐的方法创建自定义组件。我们创建了一个时间线组件,但此方法可以用于创建您想要的任何类型的自定义组件。
使用 Bootstrap 5 CSS 自定义属性
Bootstrap 5 在其编译后的 CSS 文件(bootstrap/dist/css/bootstrap.css)中包含了许多 CSS 自定义属性。这使我们能够全局访问颜色、排版和边框的值,以及当加载 Bootstrap 5 CSS 时,对大多数组件和一些工具的局部访问。使用这些 CSS 自定义属性,我们可以进行自定义,而无需使用 CSS 预处理器重新编译 Sass 代码。
CSS 自定义属性或 CSS 变量?
CSS 自定义属性也常被称为 CSS 变量。这也是 Bootstrap 团队在官方文档中称呼它们的方式,但在此章节中,我将称其为 CSS 自定义属性,以更好地区分它们与 Sass 变量。
CSS 自定义属性组
在 Bootstrap 5 中,CSS 自定义属性分为三大组:
-
根 CSS 自定义属性
-
组件 CSS 自定义属性
-
工具 CSS 自定义属性
根 CSS 自定义属性
根 CSS 自定义属性添加到 :root 伪类,这相当于 HTML 文档中的 <html> 元素。这种放置方式使我们能够从页面上的所有其他 HTML 元素全局访问它们。它们位于编译后的 Bootstrap 5 CSS (bootstrap/dist/css/bootstrap.css) 中的所有其他代码之前。
根自定义属性是由 _root.scss 文件生成的。文件的前一部分通过使用 $colors、$grays、$theme-colors 和 $theme-colors-rgb 映射以及一些其他 CSS 自定义属性的 Sass 循环来生成各种颜色的 CSS 自定义属性。文件的下一部分生成各种排版样式的 CSS 自定义属性,例如字体堆栈和 <body> 元素的基本样式,以及默认 $gradient 的 CSS 自定义属性。文件的最后一部分生成边框和边框半径的 CSS 自定义属性。大多数排版 CSS 自定义属性由 _reboot.scss 文件用于样式化 <body> 元素,边框和边框半径的 CSS 自定义属性用于生成边框和边框半径工具以及一些组件中。最后,颜色的 CSS 自定义属性被简单地全局可用,以便用于自定义。
下面是一个如何通过覆盖以下 CSS 自定义属性来更改主要、次要和成功颜色的示例:
:root {
--bs-primary: red;
--bs-secondary: green;
--bs-success: blue;
--bs-primary-rgb: #{to-rgb(red)};
--bs-secondary-rgb: #{to-rgb(green)};
--bs-success-rgb: #{to-rgb(blue)};
}
这应该放在编译后的 Bootstrap 5 代码之后某处才能工作。示例尚未在我们的网站上实现,这里只是作为一个如何使用根 CSS 自定义属性的示例。
组件 CSS 自定义属性
Bootstrap 5 的组件 CSS 自定义属性是局部作用域的,仅限于单个组件。由于它们是局部的,因此只能通过定义它们的元素访问,而不是像根自定义属性那样全局访问。所有组件,除了滚动跟踪和关闭按钮组件,都有 CSS 自定义属性。
在组件的局部 .scss 文件中,使用 Sass 变量和 CSS 自定义属性的技巧如下:
-
CSS 自定义属性被添加到组件的父类(或主类)中
-
_variables.scss中的 Sass 变量被分配为 CSS 自定义属性的值 -
CSS 自定义属性被用作常规 CSS 属性的值
下面是展示这个技巧的 badge 组件的源代码(注释已被移除):
bootstrap/scss/_badge.scss
.badge {
--#{$prefix}badge-padding-x: #{$badge-padding-x};
--#{$prefix}badge-padding-y: #{$badge-padding-y};
@include rfs($badge-font-size, --#{$prefix}badge-font-
size);
--#{$prefix}badge-font-weight: #{$badge-font-weight};
--#{$prefix}badge-color: #{$badge-color};
--#{$prefix}badge-border-radius: #{$badge-border-radius};
display: inline-block;
padding: var(--#{$prefix}badge-padding-y) var(
--#{$prefix}badge-padding-x);
@include font-size(var(--#{$prefix}badge-font-size));
font-weight: var(--#{$prefix}badge-font-weight);
line-height: 1;
color: var(--#{$prefix}badge-color);
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: var(--#{$prefix}badge-border-radius, 0);
@include gradient-bg();
&:empty {
display: none;
}
}
下面是这个组件的编译后的 CSS:
bootstrap/dist/css/bootstrap.css 行 4809-4829
.badge {
--bs-badge-padding-x: 0.65em;
--bs-badge-padding-y: 0.35em;
--bs-badge-font-size: 0.75em;
--bs-badge-font-weight: 700;
--bs-badge-color: #fff;
--bs-badge-border-radius: 0.375rem;
display: inline-block;
padding: var(--bs-badge-padding-y) var(--bs-badge-
padding-x);
font-size: var(--bs-badge-font-size);
font-weight: var(--bs-badge-font-weight);
line-height: 1;
color: var(--bs-badge-color);
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: var(--bs-badge-border-radius, 0);
}
.badge:empty {
display: none;
}
我们可以看到该组件有六个不同的 CSS 自定义属性,它们不是默认使用的。相反,它们可供我们自定义此组件使用。我们将通过以下代码行增加水平和垂直填充来利用这一点:
part-3/chapter-10/website/scss/_custom-styles.scss 行 74-77
.badge {
--bs-badge-padding-x: 1em;
--bs-badge-padding-y: 0.7em;
}
当我们编译了 CSS 后,现在我们将看到这些 CSS 自定义属性覆盖生效,对徽章组件增加了填充。
工具 CSS 自定义属性
通用 CSS 自定义属性被定义为背景、颜色和边框工具,并且它们的作用域是局部的,就像组件 CSS 自定义属性一样。使用这些 CSS 自定义属性,例如,我们可以控制rgba()颜色的 alpha 透明度值。
以背景工具为例,.bg-primary工具具有以下 CSS 样式:
bootstrap/dist/css/bootstrap.css 行 8402-8405
.bg-primary {
--bs-bg-opacity: 1;
background-color: rgba(var(--bs-primary-rgb), var(--bs-
bg-opacity)) !important;
}
我们可以看到,工具具有--bs-bg-opacity: 1 CSS 自定义属性,该属性被background-color属性用来指定rgba()颜色函数的a部分。现在,例如,我们可以添加.bg-opacity-25或.bg-opacity-50类到同一个元素上,以将不透明度从1改为0.25或0.5。如果我们想要不透明度在两者之间,我们可以覆盖 CSS 自定义属性,例如,如下所示:
HTML
<div class="bg-primary" style="--bs-bg-opacity: 0.33">Primary background with an opacity of 0.33</div>
CSS 自定义属性在定制化方面的局限性
你可以使用 CSS 自定义属性进行强大的定制化。然而,你并不能在所有情况下都替换 Sass 变量的使用。作为一个例子,让我们考虑全局边框半径的样式。这些最初在_variables.scss文件中定义为六个不同的 Sass 变量:
bootstrap/scss/_variables.scss 行 495-500
$border-radius: .375rem !default;
$border-radius-sm: .25rem !default;
$border-radius-lg: .5rem !default;
$border-radius-xl: 1rem !default;
$border-radius-2xl: 2rem !default;
$border-radius-pill: 50rem !default;
这些 Sass 变量随后被用于在_root.scss文件中生成边框半径的 CSS 自定义属性,如下所示:
bootstrap/scss/_root.scss
--#{$prefix}border-radius: #{$border-radius};
--#{$prefix}border-radius-sm: #{$border-radius-sm};
--#{$prefix}border-radius-lg: #{$border-radius-lg};
--#{$prefix}border-radius-xl: #{$border-radius-xl};
--#{$prefix}border-radius-2xl: #{$border-radius-2xl};
--#{$prefix}border-radius-pill: #{$border-radius-pill};
如果我们现在使用编译后的 Bootstrap 5 CSS,并且想要改变按钮的边框半径,我们可以在自己的 CSS 中针对.btn,并像这样覆盖边框半径的 CSS 自定义属性:
.btn {
--bs-btn-border-radius: 0.75rem;
}
这里的局限性在于我们无法使用 CSS 自定义属性定义跨多个组件使用的$border-radius Sass 变量。因此,在我们的例子中,按钮元素的边框半径会改变,但输入元素的边框半径不会改变,尽管在 Sass 代码中它们使用相同的边框半径值:
bootstrap/scss/_variables.scss 行 774 和 835
$btn-border-radius: $border-radius !default;
$input-border-radius: $border-radius !default;
如我们所见,这是一个局限性。因此,尽管使用 CSS 自定义属性进行定制化非常强大,我们不需要使用 CSS 预处理器,但我们不能像使用 Sass 那样进行相同的定制化。尽管如此,我们现在将看看一些更多关于如何使用 CSS 自定义属性进行定制的例子。
深色主题
我们之前看到了如何使用color-scheme混合和颜色变量创建深色主题的样式。同样,也可以使用媒体查询和 CSS 自定义属性来创建相同的深色主题样式。实现这一功能的必要 CSS 代码如下:
part-3/chapter-10/website/css/darkmode.css
@media (prefers-color-scheme: dark) {
body {
background-color: var(--bs-dark);
color: var(--bs-light);
}
.bg-light, .jumbotron {
background-color: var(--bs-dark) !important;
}
.bg-dark {
background-color: var(--bs-gray-700) !important;
}
.accordion-button,
.accordion-item,
.card,
.list-group-item {
background-color: var(--bs-dark);
}
.accordion-button,
.breadcrumb-item.active,
.figure-caption,
.list-group-item,
.navbar-light .navbar-brand,
.navbar-light .navbar-nav .nav-link {
color: var(--bs-light);
}
}
要使用它,你只需在<head>中包含darkmode.css文件,位置在编译后的 Bootstrap 5 CSS 文件之后某处;例如,如下所示:
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/darkmode.css">
<link rel="stylesheet" href="icons/bootstrap-icons.css">
由于我们已经在网站上使用 Sass 创建了深色主题,我们将保留它,而不会更新我们的代码以使用 darkmode.css 文件,但如果你需要使用,它已包含在 css 文件夹中。如果你选择使用它,请记住在 _custom-styles.scss 文件中移除深色主题的样式。
面包屑导航
我们之前通过在 _default-variable-overrides.scss 文件中覆盖 $breadcrumb-divider 变量来更改面包屑分隔符。我们可以使用 --bs-breadcrumb-divider CSS 自定义属性来代替,因为 Sass 变量实际上只是 CSS 自定义属性的回退。
为了将这个更新应用到我们的网站上,我们首先将移除我们对 breadcrumb 分隔符的 Sass 定制化:
part-3/chapter-10/website/scss/_default-variable-overrides.scss
// Breadcrumb
$breadcrumb-divider: quote("–");
相反,我们现在将通过在包含面包屑组件的 <nav> 元素上的行内样式中分配值来使用 CSS 自定义属性,这是唯一使用该组件的 商店 和 产品 页面:
part-3/chapter-10/website/shop.xhtml 行 216-222
<nav aria-label="Breadcrumb navigation" style="--bs-breadcrumb-divider: '–';">
<ol class="breadcrumb mb-2 mb-lg-0">
<li class="breadcrumb-item"><a href="#">Shop</a></li>
<li class="breadcrumb-item"><a
href="#">Category</a></li>
<li class="breadcrumb-item active" aria-
current="page">Subcategory</li>
</ol>
</nav>
我们在浏览器中不会看到任何视觉变化,这意味着我们已经成功更新了我们的代码。
辅助工具
我们之前通过创建 $custom-ratio 映射并将其与默认的 $aspect-ratios 映射合并,添加了一个新的比例辅助类,其宽高比为 5x3。这需要在 _variable-value-using-variable.scss 文件末尾编写几行代码。我们可以使用 --bs-aspect-ratio CSS 自定义属性来代替,因为比例辅助工具的 Sass 代码已经使用 $aspect-ratios 映射中的值来设置该 CSS 自定义属性的值。
为了将这个更新应用到我们的网站上,我们首先将移除我们对比例辅助工具的 Sass 定制化:
part-3/chapter-10/website/scss/_variable-value-using-variable.scss
// Ratio
// Create custom ratio map
$custom-ratio: (
"5x3": calc(3 / 5 * 100%)
);
// Merge "$aspect-ratios" and "$custom-ratio"
$aspect-ratios: map-merge($aspect-ratios, $custom-ratio);
相反,我们现在将通过在包含 Google 地图 <iframe> 的 联系 页面上的比例辅助工具的行内样式中分配值来使用 CSS 自定义属性,这是唯一使用比例辅助工具的地方:
part-3/chapter-10/website/contact.xhtml 行 177-179
<div class="ratio ratio-5x3" style="--bs-aspect-ratio: 60%;">
<iframe src="https://www.google.com/maps/
embed?pb=!1m18!1m12!1m3!1d3022.6175453420647!2d-
73.98784413479707!3d40.748440379327945!2m3!1f0!2f
0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89c259a9aeb
1c6b5%3A0x35b1cfbc89a6097f!2sEmpire+State+Building
%2C+350+5th+Ave%2C+New+York%2C+NY+10118%2C+USA
!5e0!3m2!1sda!2sdk!4v1491841211721"
allowfullscreen></iframe>
</div>
为了保持简洁,我们使用 60% 的值,这仅仅是 calc(3 / 5 * 100%) 的结果。现在,当我们使用浏览器查看更新后的代码时,宽高比将保持不变。
CSS 自定义属性的前缀
默认情况下,所有 Bootstrap 5 CSS 自定义属性都以前缀 bs- 开头(前缀 bs- 前的双短横线 -- 是声明 CSS 自定义属性的方式,并且不能省略)。如果你想更改这个前缀,可以在 _variables.scss 文件中定义的 $prefix 变量上进行覆盖。这个变量的默认值是 bs-。
已废弃的 CSS 自定义属性前缀变量
用于指定 CSS 自定义属性前缀的变量曾经是 $variable-prefix,但从 Bootstrap 的 v5.2.0 版本开始,它将被弃用并替换为更短的 $prefix。因此,在当前版本 v5.2.0 中,这两个变量都存在于代码中。
使用 RFS Sass 插件
RFS 被官方描述为“单位缩放引擎”,它“自动化响应式缩放”。换句话说,RFS 是一组 Sass 混入和函数,用于根据视口宽度计算自动响应式 CSS 值。作为“响应式字体大小”的缩写,它最初是为了字体缩放而开发的,但现在它几乎可以缩放任何 CSS 属性的任何值。RFS 可以从其官方 GitHub 网站下载,网址为 github.com/twbs/rfs/,或者通过 NPM 使用命令 npm install rfs 进行安装。正如您从 GitHub 网址中看到的,该存储库与 Bootstrap 并列存在,因为 RFS 是 Bootstrap 背后团队的一个侧项目。实际上,RFS 作为 Bootstrap 5 的 _rfs.scss 文件包含在 vendor 文件夹中,用于缩放字体大小。这在标题中最为明显。RFS 默认通过全局选项 $enable-rfs 启用,因此也可以通过将该变量设置为 false 来禁用,正如我们在 第四章 中看到的,Bootstrap 5 全局选项和颜色。
RFS 的语法如下:
@include rfs([max-value], [property])
[max-value] 是您希望在大型屏幕上指定的 [property] 的值。RFS 将在视口宽度为 1200px 或更大时使用此值(因此从 xl 断点开始)。在此之下,该值将根据视口宽度动态缩放,直到达到基本值 1.25rem,之后将不再缩放。这两个选项可以使用 $rfs-breakpoint 和 $rfs-base-value 变量以及其他选项进行自定义。
我们还可以使用以下用于字体大小、填充和边距的缩写混入,因此我们不需要显式指定属性:
bootstrap/scss/vendor/_rfs.scss
// Shorthand helper mixins
@mixin font-size($value) {
@include rfs($value);
}
@mixin padding($value) {
@include rfs($value, padding);
}
@mixin padding-top($value) {
@include rfs($value, padding-top);
}
@mixin padding-right($value) {
@include rfs($value, padding-right);
}
@mixin padding-bottom($value) {
@include rfs($value, padding-bottom);
}
@mixin padding-left($value) {
@include rfs($value, padding-left);
}
@mixin margin($value) {
@include rfs($value, margin);
}
@mixin margin-top($value) {
@include rfs($value, margin-top);
}
@mixin margin-right($value) {
@include rfs($value, margin-right);
}
@mixin margin-bottom($value) {
@include rfs($value, margin-bottom);
}
@mixin margin-left($value) {
@include rfs($value, margin-left);
}
现在,让我们看看一个使用 RFS 设置盒子填充的示例。在 HTML 中,我们首先有一个使用 RFS 进行填充的盒子,然后是另一个使用间距实用工具进行填充的盒子:
part-3/chapter-10/examples/rfs/index.xhtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<title>RFS</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container mt-3">
<p>Box with RFS used for padding</p>
<div class="box border mb-3">
<h1 class="m-0">Heading</h1>
</div>
<p>Box with spacing utility used for padding</p>
<div class="p-5 border">
<h1 class="m-0">Heading</h1>
</div>
</div>
</body>
</html>
然后,在我们的 Sass 中,我们首先导入 Bootstrap 5,然后像这样在我们的 .box 类上使用填充的缩写混入:
part-3/chapter-10/examples/rfs/scss/style.scss
// Bootstrap 5
@import "../../../../../bootstrap/scss/bootstrap.scss";
.box {
@include padding(3rem);
}
我们使用的是 3rem 的值,这与第一个盒子上的 .p-5 类使用的值相同。这样,很容易看出 RFS 做出的差异。以下是两个显示差异的屏幕截图,我还建议您在浏览器中查看示例,在那里您可以更好地看到 RFS 在调整浏览器宽度时进行的自动计算。

图 10.10 – 在小型设备(576px)上查看:正在使用计算值进行填充

图 10.11 – 在超大设备(1200px)上查看:正在使用最大值进行填充
摘要
在本章中,我们探讨了与 Bootstrap 5 相关的各种高级 Sass 和 CSS 功能。我们首先看到了如何使用各种 Bootstrap 5 混入(mixins)和函数,以及如何使用 extend 功能实现各种目的。然后,我们学习了使用 Bootstrap 5 变量、混入和函数创建自定义组件的推荐方法。之后,我们了解了如何使用 Bootstrap 5 的 CSS 自定义属性来创建深色主题,以及如何自定义组件和辅助工具。最后,我们学习了如何使用 Bootstrap 的侧项目 RFS 来计算自动响应式 CSS 值。
在下一章中,我们将更详细地探讨 Bootstrap 5 的 JavaScript 功能。
第十一章:第十一章: 使用 Bootstrap 5 的高级 JavaScript 特性
在本章中,我们将学习一些可以与 Bootstrap 5 交互式组件一起使用的 JavaScript 高级特性。首先,我们将快速概述交互式组件,并查看它们在依赖项和初始化方面的共同要求。然后,我们将看到如何使用数据属性或 JavaScript 初始化交互式组件。接着,我们将看到如何使用数据属性或 JavaScript 定义选项,最后,我们将更详细地探讨如何使用 JavaScript 进行方法和事件处理。
在本章中,我们将涵盖以下主要主题:
-
Bootstrap 5 的交互式组件
-
初始化交互式组件
-
定义交互式组件的选项
-
使用 JavaScript 方法
-
使用 JavaScript 事件
技术要求
为了预览示例,你需要一个代码编辑器和浏览器。所有代码示例的源代码都可以在这里找到:
https://github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide
Bootstrap 5 的交互式组件
我们将从这个章节开始,先对 Bootstrap 5 的交互式组件进行概述。对于这里列出的每个组件,我们将看到它使用了哪个 JavaScript 文件,是否需要自定义初始化,它有哪些选项、方法和事件,是否有任何依赖项,对于其中的一些,我们还会提供一些额外的信息。在接下来的章节中,我们将更详细地探讨初始化、选项、方法和事件,因此这应该只被视为一个概述。列表的最后,还有一个总结,以突出最重要的差异。
折叠面板
此组件是使用后面描述的折叠组件构建的。
警告框
alert.js
自定义初始化: 否
选项: 无
close, dispose, getInstance, getOrCreateInstance
close.bs.alert, closed.bs.alert
依赖项: 无
此组件可以使用关闭按钮组件关闭。
按钮
button.js
自定义初始化: 否
选项: 无
toggle, dispose, getInstance, getOrCreateInstance
事件: 无
依赖项: 无
轮播图
carousel.js
自定义初始化: 否
interval, keyboard, pause, ride, wrap, touch
cycle, pause, prev, next, nextWhenVisible, to, dispose, getInstance, getOrCreateInstance
slide.bs.carousel, slid.bs.carousel
依赖项: 无
折叠组件
collapse.js
自定义初始化: 否
parent, toggle
toggle, show, hide, dispose, getInstance, getOrCreateInstance
show.bs.collapse, shown.bs.collapse, hide.bs.collapse, hidden.bs.collapse
依赖项: 无
下拉菜单
dropdown.js
自定义初始化: 否
boundary, reference, display, offset, autoClose, popperConfig
toggle, show, hide, update, dispose, getInstance, getOrCreateInstance
show.bs.dropdown, shown.bs.dropdown, hide.bs.dropdown, hidden.bs.dropdown
依赖: Popper
此组件需要外部第三方库 Popper 进行定位。它必须在 bootstrap.js 之前包含,或者使用包含 Popper 的 bootstrap.bundle.js。
列表组
此组件使用 tab.js 基于列表组创建标签导航。请参考关于导航和标签的详细信息,它们使用相同的 JavaScript 文件。
Modal
modal.js
自定义初始化: 否
backdrop, keyboard, focus
toggle, show, hide, handleUpdate, dispose, getInstance, getOrCreateInstance
show.bs.modal, shown.bs.modal, hide.bs.modal, hidden.bs.modal, hidePrevented.bs.modal
依赖: 无
导航和标签
tab.js
自定义初始化: 否
选项: 无
show, dispose, getInstance, getOrCreateInstance
show.bs.tab, shown.bs.tab, hide.bs.tab, hidden.bs.tab
依赖: 无
此组件使用的 JavaScript 文件也用于列表组组件。
Offcanvas
offcanvas.js
自定义初始化: 否
backdrop, keyboard, scroll
toggle, show, hide, getInstance, getOrCreateInstance
show.bs.offcanvas, shown.bs.offcanvas, hide.bs.offcanvas, hidden.bs.offcanvas
依赖: 无
Popover
popover.js
自定义初始化: 是
animation, container, content, delay, html, placement, selector, template, title, trigger, fallbackPlacements, boundary, customClass, sanitize, allowList, sanitizeFn, offset, popperConfig
show, hide, toggle, dispose, enable, disable, toggleEnabled, update, getInstance, getOrCreateInstance
show.bs.popover, shown.bs.popover, hide.bs.popover, hidden.bs.popover, inserted.bs.popover
tooltip.js, Popover
此组件需要 tooltip.js 作为依赖。它还需要外部第三方库 Popper 进行定位。后者必须在 bootstrap.js 之前包含,或者使用包含 Popper 的 bootstrap.bundle.js。
Scrollspy
scrollspy.js
自定义初始化: 否
rootMargin, smoothScroll, target
refresh, dispose, getInstance, getOrCreateInstance
activate.bs.scrollspy
依赖: 无
Toast
toast.js
自定义初始化: 是
animation, autohide, delay
show, hide, dispose, getInstance, getOrCreateInstance
show.bs.toast, shown.bs.toast, hide.bs.toast, hidden.bs.toast
依赖: 无
Tooltip
tooltip.js
自定义初始化: 是
animation, container, delay, html, placement, selector, template, title, trigger, fallbackPlacements, boundary, customClass, sanitize, allowList, sanitizeFn, offset, popperConfig
show, hide, toggle, dispose, enable, disable, toggleEnabled, update, getInstance, getOrCreateInstance
show.bs.tooltip, shown.bs.tooltip, hide.bs.tooltip, hidden.bs.tooltip, inserted.bs.tooltip
依赖: 弹出
此组件需要外部第三方库 Popper 来定位。它必须在 bootstrap.js 之前包含,或者通过使用包含 Popper 的 bootstrap.bundle.js。
弹出组件需要 tooltip.js 文件作为依赖。
我们刚刚列出并概述了所有 15 个以某种方式使用 JavaScript 的组件。现在,我们将总结这些内容,并突出组件之间的最重要的差异。因此,在接下来的四个标题下,我们将看到哪些组件脱颖而出。
需要初始化
组件: 弹出、通知、工具提示
由于性能原因,这些组件不能使用数据属性初始化。因此,它们必须使用自定义 JavaScript 来初始化。我们将在 初始化交互式组件 部分看到如何操作。
有依赖
组件: 下拉菜单、弹出、工具提示
这些组件都需要外部第三方库 Popper 来定位。它必须在 bootstrap.js 之前包含,或者通过使用包含 Popper 的 bootstrap.bundle.js。
此外,弹出组件还需要工具提示组件的 tooltip.js JavaScript 文件作为依赖。
没有选项
组件: 警告、按钮、导航和标签页
这些组件没有任何选项。
没有事件
组件: 按钮
此组件没有任何事件。
初始化交互式组件
在本节中,我们将看到我们可以以两种不同的方式初始化交互式组件。首先,我们将看到如何在 HTML 中使用数据属性来初始化,这是默认方式,你可能已经在使用了。然后,我们将看到如何使用 JavaScript 来初始化。我们可以使用数据属性初始化大多数与 Bootstrap 5 一起提供的交互式组件,而无需添加任何额外的 JavaScript 代码,而对于其中的一些组件,我们必须使用自己的 JavaScript 来初始化。
使用数据属性初始化交互式组件
我们可以使用数据属性初始化大多数与 Bootstrap 5 一起提供的交互式组件,而无需添加任何额外的 JavaScript 代码。对于大多数组件,我们使用 data-bs-toggle 数据属性,其值是组件的名称,如下所示:
HTML
<button type="button" class="btn btn-primary" data-bs-toggle="button">Button</button>
然而,对于轮播组件,我们必须使用 data-bs-ride="carousel",对于滚动监听组件,我们必须使用 data-bs-spy="scroll",并且,要关闭警告或偏移画布组件,我们必须使用 data-bs-dismiss="[alert/offcanvas]"。
其他所需的数据属性
一些组件需要各种其他数据属性才能正常工作。上述提到的数据属性只是用于初始化它们的属性。
使用 JavaScript 初始化交互式组件
正如我们在本章开头的列表中所看到的,我们必须使用自己的 JavaScript 代码来初始化一些交互式组件。
例如,我们想要为以下徽章组件创建一个提示组件:
HTML
<div class="badge bg-secondary" title="Tooltip for badge">Badge with tooltip</div>
<div> 标签具有 title 属性,该属性被提示组件使用。
语法
我们可以通过在 JavaScript 中使用构造函数创建并初始化一个类的对象实例来初始化一个交互式组件,使用 new 关键字。
该语法的语法如下:
JavaScript
var tooltip = new bootstrap.Tooltip(element, options)
在这里,element 可以是一个 DOM 元素或 CSS 选择器,而 options 是一个对象,是可选的。即使我们使用 JavaScript 初始化组件,也可以使用数据属性定义选项。我们将在 为交互式组件定义选项 部分了解更多关于选项的内容。
使用 DOM 元素
要使用 DOM 元素初始化一个交互式组件,我们必须首先将其存储在一个变量中,然后使用该变量作为 DOM 元素的引用。以下是一个示例:
part-3/chapter-11/examples/initialization/index.xhtml 行 14
<div class="badge bg-secondary" title="Tooltip for badge" id="tooltipDOM">Badge with tooltip</div>
part-3/chapter-11/examples/initialization/js/script.js 行 1-2
var tooltipDOMelement = document.getElementById('tooltipDOM');
var tooltipDOM = new bootstrap.Tooltip(tooltipDOMelement);
在前面的代码中,我们将具有 id="tooltipDOM" 的元素存储在 element 变量中,然后将其作为参数传递给构造函数。我们没有传递任何选项,因为我们将在此章的稍后部分更详细地介绍这一点。
使用 CSS 选择器
要使用 CSS 选择器初始化一个交互式组件,我们可以简单地将它作为构造函数的参数传递。然后使用 querySelector() 方法找到该元素。以下是一个使用 <div> 元素的 ID 作为选择器的示例:
part-3/chapter-11/examples/initialization/index.xhtml 行 19
<div class="badge bg-secondary" title="Tooltip for badge" id="tooltipCSS">Badge with tooltip</div>
part-3/chapter-11/examples/initialization/js/script.js 行 4
var tooltip = new bootstrap.Tooltip('#tooltipCSS');
初始化多个组件
交互式组件的各种 JavaScript 插件仅支持单个元素。因此,要初始化多个元素,我们可以为列表或数组中的每个元素调用构造函数。现在我们将看到两个不同的示例,说明我们如何做到这一点。
使用 for 循环
对于第一个示例,我们将使用以下 HTML,其中包含三个具有相同 tooltipLoop 类的相同徽章组件:
part-3/chapter-11/examples/initialization/index.xhtml 行 24-26
<div class="badge bg-secondary tooltipLoop" title="Tooltip for badge">Badge with tooltip</div>
<div class="badge bg-secondary tooltipLoop" title="Tooltip for badge">Badge with tooltip</div>
<div class="badge bg-secondary tooltipLoop" title="Tooltip for badge">Badge with tooltip</div>
当使用 for 循环时,我们首先将所有 <div> 元素存储在 tooltipLoopElements 变量中。然后,我们遍历这个 NodeList 并为每个元素调用构造函数:
part-3/chapter-11/examples/initialization/js/script.js 行 6-9
var tooltipLoopElements = document.querySelectorAll('.tooltipLoop');
for (var i = 0; i < tooltipLoopElements.length; i++) {
new bootstrap.Tooltip(tooltipLoopElements[i])
}
使用 map 方法
对于第二个示例,我们将使用以下 HTML,其中包含三个具有相同 tooltipMap 类的相同徽章组件:
part-3/chapter-11/examples/initialization/index.xhtml 行 31-33
<div class="badge bg-secondary tooltipMap" title="Tooltip for badge">Badge with tooltip</div>
<div class="badge bg-secondary tooltipMap" title="Tooltip for badge">Badge with tooltip</div>
<div class="badge bg-secondary tooltipMap" title="Tooltip for badge">Badge with tooltip</div>
当使用map()方法时,我们首先将所有<div>元素存储在tooltipMapElements变量中。然而,这次我们使用slice()和call()方法将 NodeList 转换为数组。然后,我们使用map()方法创建一个新的数组并将其存储在tooltipMap变量中。对于数组中的每个元素,我们像之前一样调用构造函数:
part-3/chapter-11/examples/initialization/js/script.js 行 11-14
var tooltipMapElements = [].slice.call(document.querySelectorAll('.tooltipMap'));
var tooltipMap = tooltipMapElements.map(function(tooltipMapElement) {
return new bootstrap.Tooltip(tooltipMapElement)
});
下拉组件所需的数据属性
即使您选择使用 JavaScript 初始化下拉组件,触发元素的data-bs-toggle="dropdown"数据属性仍然是必需的。
我们现在已经学会了如何以各种方式初始化交互式组件。我们将继续学习如何为交互式组件定义选项。
定义交互式组件的选项
在本章开头列出的列表中,我们看到了交互式组件可用的选项。在 Bootstrap 5 的官方文档中,您将找到一个表格,描述了每个组件的所有可用选项(如果有)。在这个表格中,您将找到每个选项的名称、类型、默认值和描述。您可以通过以下链接访问官方文档中的组件:getbootstrap.com/docs/5.1/components。
可以通过 JavaScript 设置同一类型的所有组件的默认选项和一组组件的常见选项,而单个组件的选项可以通过数据属性或 JavaScript 传递。现在让我们看看这是如何完成的。
定义默认选项
您可以使用以下语法为组件的选项更改默认值:
JavaScript
bootstrap.[component name].Default.[option name] = [option value];
例如,我们可以将我们的提示框组件设置为默认延迟为 1,000 毫秒,如下所示:
JavaScript
bootstrap.Tooltip.Default.delay = 1000;
使用数据属性定义选项
要使用数据属性定义选项,我们将选项名称附加到data-bs-,并且选项名称的案例类型应从camelCase更改为kebab-case。
现在,让我们看看如何使用触发选项初始化提示框组件,该选项接受字符串类型的值。默认值为‘hover focus’,可能的值有‘click | hover | focus | manual’。我们将使用以下代码仅使用点击来触发提示框:
HTML
<a href="#" id="tooltip" title="Tooltip for link" data-bs-trigger="click">Link</a>
现在提示框将仅在点击时触发以显示和隐藏——就像弹出组件一样。请注意,仅凭之前的代码本身不会初始化提示框组件。正如我们刚刚学到的,这必须通过我们自己的 JavaScript 代码来完成:
无法使用数据属性设置的选项
由于安全原因,以下由弹出框和提示组件使用的选项不能使用数据属性设置:sanitize、sanitizeFn和allowList。这些都与在提示或弹出框的内容中使用 HTML 有关。
使用 JavaScript 定义选项
如本章前面所述,初始化交互式组件时,可以通过构造函数传递一个可选的options对象。再次强调,语法如下:
var tooltip = new bootstrap.Tooltip(element, options)
要使用对象定义一个选项,我们只需将选项名称作为对象的属性,然后根据选项类型给出一个有效的值。初始化与之前相同的提示组件,将trigger选项设置为click,将看起来像这样:
HTML
<a href="#" id="tooltip" title="Tooltip for link">Link</a>
JavaScript
var tooltip = new bootstrap.Tooltip('#tooltip', { trigger: 'click' })
现在提示框将仅在点击时触发显示和隐藏。
定义默认、通用和个体选项
如前所述,我们可以使用 JavaScript 和数据属性为组件定义默认、通用和个体选项。如果你想要为同一类型的所有组件定义一些默认选项,为组件组定义具有相同值的选项,以及为每个组件实例定义具有不同值的个体选项,这将非常有用。
我们现在将看到一个示例,我们将利用所有这些。在我们的 HTML 中,我们有四个徽章组件,我们想要为它们添加一个提示组件。在每个<div>元素上,我们使用data-bs-placement数据属性定义提示的位置:
part-3/chapter-11/examples/options/index.xhtml
<div class="badge bg-secondary tooltipOnClick" title="Tooltip on top" data-bs-placement="top">Badge with tooltip on top</div>
<div class="badge bg-secondary tooltipOnClick" title="Tooltip on bottom" data-bs-placement="bottom">Badge with tooltip on bottom</div>
<div class="badge bg-secondary tooltipOnClick" title="Tooltip on left" data-bs-placement="left">Badge with tooltip on left</div>
<div class="badge bg-secondary tooltipOnClick" title="Tooltip on right" data-bs-placement="right">Badge with tooltip on right</div>
然后,在我们的 JavaScript 中,我们首先定义delay的默认选项并将其设置为1000毫秒。之后,我们使用trigger选项设置为‘click’来初始化组件:
part-3/chapter-11/examples/options/js/script.js
bootstrap.Tooltip.Default.delay = 1000;
var tooltipElementList = document.querySelectorAll('.tooltipOnClick');
for (var i = 0; i < tooltipElementList.length; i++) {
new bootstrap.Tooltip(tooltipElementList[i], { trigger:
'click' })
}
现在四个徽章组件将各自拥有一个提示组件,点击时延迟 1,000 毫秒触发。提示框将分别放置在顶部、底部、左侧和右侧。
使用数据属性和 JavaScript 设置相同选项
如果你同时使用数据属性和 JavaScript 指定相同的选项,JavaScript 设置将优先。
使用 JavaScript 方法
在本章开头列表中,我们看到了所有交互式组件都有方法。在 Bootstrap 5 的官方文档中,你可以找到一个表格,描述了每个组件的所有可用方法。在这个表格中,你可以找到每个方法的名称和描述。你可以通过以下链接访问官方文档中的组件:getbootstrap.com/docs/5.2/components。
现在,我们将看到一些如何使用特定方法的示例。在我们的示例页面上,我们首先有一个默认的提示组件用于比较。其 HTML 代码如下:
part-3/chapter-11/examples/methods/index.xhtml 行 15
<div class="badge bg-secondary" id="tooltipDefault" title="Default tooltip">Badge with default tooltip</div>
提示具有id="tooltipDefault"属性,我们使用以下 JavaScript 对其进行初始化:
part-3/chapter-11/examples/methods/js/script.js 行 1
var tooltipDefault = new bootstrap.Tooltip('#tooltipDefault', { placement: "bottom" });
如我们所见,提示使用placement选项放置在底部。这只是为了使示例页面在视觉上更好。
对于示例页面上的下一个提示组件,我们希望它在页面加载时显示,同时禁用悬停和聚焦触发。HTML 代码如下:
part-3/chapter-11/examples/methods/index.xhtml 行 21
<div class="badge bg-secondary" id="tooltipOnLoad" title="Tooltip triggered on load">Badge with tooltip triggered on load</div>
提示具有id="tooltipOnLoad"属性,我们将使用它进行初始化。JavaScript 代码如下:
part-3/chapter-11/examples/methods/js/script.js 行 3-4
var tooltipOnLoad = new bootstrap.Tooltip('#tooltipOnLoad', { trigger: "manual", placement: "bottom" });
tooltipOnLoad.show();
提示使用placement选项放置在底部。这只是为了使示例页面在视觉上更好。
对于示例页面上的最终提示组件,我们希望当我们点击页面上的另一个按钮时切换其可见性。这个 HTML 代码如下:
part-3/chapter-11/examples/methods/index.xhtml 行 27-28
<button type="button" id="triggerForTooltip" class="btn btn-secondary mb-4">Trigger for tooltip</button><br>
<div class="badge bg-secondary" id="tooltipOnButtonClick" title="Tooltip toggled on button click">Badge with tooltip toggled on button click</div>
按钮具有id="triggerForTooltip"属性,我们将使用它来附加事件监听器,提示具有id="tooltipOnButtonClick"属性,我们将使用它进行初始化。JavaScript 代码如下:
part-3/chapter-11/examples/methods/js/script.js 行 6-10
var tooltipOnButtonClick = new bootstrap.Tooltip('#tooltipOnButtonClick', { trigger: "manual", placement: "bottom" });
var triggerForTooltip = document.getElementById('triggerForTooltip');
triggerForTooltip.addEventListener('click', function() {
tooltipOnButtonClick.toggle();
})
第一行与上一个示例类似:使用placement选项将提示放置在底部,并将触发提示的方法设置为manual。下面,我们首先获取按钮元素,然后将其附加一个click事件,并在按钮被点击时执行toggle()方法。这将显示和隐藏提示。
异步方法和转换
重要的是要知道所有方法都是异步的,并且开始一个转换过程。一旦转换开始,它们就会返回调用者。这意味着在组件正在转换时对其进行的调用将被忽略。以下是一个示例,它将显示模态框,但不会隐藏它,因为hide()方法是在show()方法之后立即调用的,因此是在模态框显示转换完成之前:
JavaScript
var modalElement = document.getElementById('modal');
var modal = bootstrap.Modal.getOrCreateInstance(modalElement);
modal.show();
modal.hide();
相反,如果我们想在转换完成后执行一些代码,我们需要监听相应的事件,如下所示:
JavaScript
var modalElement = document.getElementById('modal');
var modal = bootstrap.Modal.getOrCreateInstance(modalElement);
modal.show();
modalElement.addEventListener('shown.bs.modal', function (event) {
modal.hide();
})
现在,模态框将首先显示,然后在模态框的shown事件被触发时再次隐藏。在下一节中,我们将看到另一个如何使用 Bootstrap 5 事件的示例。
使用 JavaScript 事件
在本章开头的列表中,我们看到了大多数交互式组件都有事件。在 Bootstrap 5 的官方文档中,你可以找到一个表格,描述了每个组件的所有可用事件。在这个表格中,你可以找到每个方法的类型和描述。你可以通过此链接访问官方文档中的组件:getbootstrap.com/docs/5.2/components。
现在,我们将看到一个如何使用特定事件的示例,用于提示框组件。在我们的示例页面上,我们有一个按钮,它触发一个模态组件。在模态框的页脚中,我们有一个确认按钮,我们希望在模态框显示且过渡完成时显示提示框。
这里是 HTML 的样式:
part-3/chapter-11/examples/events/index.xhtml
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modal">Open modal</button>
<div class="modal fade" id="modal" tabindex="-1" aria-labelledby="modalTitle" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalTitle">Modal
title</h5>
<button type="button" class="btn-close" data-bs-
dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Lorem ipsum dolor sit amet, consectetur
adipiscing elit. In laoreet pellentesque lorem
sed elementum. Suspendisse maximus convallis ex.
Etiam eleifend velit leo.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
id="tooltip" title="Click here to
confirm">Confirm</button>
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
提示框具有 id="tooltip",我们将用它进行初始化,并且提示框的内容放置在 title 属性中。在 JavaScript 代码中,我们首先将模态框的 DOM 元素存储在一个变量中,并初始化提示框组件。然后,在附加到模态框的事件监听器中,我们监听 shown.bs.modal 事件,并在该事件触发时调用提示框组件的 show() 方法。此代码如下:
part-3/chapter-11/examples/events/js/script.js
var modal = document.getElementById('modal');
var tooltip = new bootstrap.Tooltip('#tooltip');
modal.addEventListener('shown.bs.modal', function (event) {
tooltip.show();
})
此示例将显示提示框,正好在模态框的过渡完成时。
带有属性的事件
旋转木马组件的两个事件具有以下附加属性:direction ("left" 或 "right"), relatedTarget (DOM 元素), from (索引号), 和 to (索引号)。
摘要
在本章中,我们学习了可以与 Bootstrap 5 的交互式组件一起使用的某些高级 JavaScript 特性。首先,我们快速概述了交互式组件,并看到了它们在依赖性和初始化方面的共同要求。然后,我们看到了如何使用数据属性或 JavaScript 初始化交互式组件。接着,我们看到了如何使用数据属性或 JavaScript 定义选项,最后,我们更详细地探讨了如何使用 JavaScript 进行方法和事件的处理。
在本书的下一章和最后一章中,我们将学习如何优化编译后的 Bootstrap 5 CSS 和 JavaScript 代码。
第十二章:第十二章:优化 Bootstrap 5 CSS 和 JavaScript 代码
在本章中,我们不会使用 Bootstrap 5 创建任何新的用户界面或自定义现有的界面。我们甚至不会查看 Bootstrap 5 文件中包含的任何源代码。相反,我们将看到在完成我们的网站创建后,我们如何优化我们的编译 Bootstrap 5 CSS 和 JavaScript 代码。
我们首先将专注于通过仅包含我们实际使用的 Bootstrap 5 Sass 部分来优化我们的样式表,并移除所有我们不使用的辅助工具和实用工具。然后我们将使用 Node.js、NPM 和 Laravel Mix 来设置一个构建过程来自动化一些任务,这将帮助我们捆绑我们组件实际使用的 JavaScript,并压缩我们的编译 CSS 和捆绑的 JavaScript。
在本章中,我们将涵盖以下主要主题:
-
仅包含使用组件的 Sass 部分
-
移除未使用的辅助工具和实用工具
-
使用 Node.js、npm 和 Laravel Mix 设置构建过程
-
使用模块打包器优化 JavaScript
-
压缩我们的编译 CSS 和捆绑的 JavaScript
技术要求
-
要预览示例,您需要一个代码编辑器和浏览器。所有代码示例的源代码都可以在这里找到:
github.com/PacktPublishing/The-Missing-Bootstrap-5-Guide。 -
要编译 Sass 到 CSS,您需要以下任何一个:
-
Node.js,如果您更喜欢使用终端(Mac)或命令提示符(Windows)的命令行界面(CLI)
-
Scout-App,如果您更喜欢图形用户界面(GUI)
-
Visual Studio Code,如果您更喜欢使用 Visual Studio Code Marketplace 中的扩展
-
所有这些方法都在第二章中解释,使用和编译 Sass。
要使用 Laravel Mix,您需要在您的计算机上安装Node.js,然后按照说明从 npm 下载所需的包。
仅包含使用组件的 Sass 部分
在本节中,我们将看到如何通过仅包含我们 HTML 代码中实际使用的 Bootstrap 5 Sass 部分来优化我们的编译 CSS。在我们这本书中早期创建的网站上,我们使用了 Bootstrap 5 的所有组件,除了 Placeholder、Popover 和 Scrollspy 组件。Scrollspy 是一个仅使用 JavaScript 的组件,因此我们将移除 Placeholder 和 Popover 组件的 Sass 部分。在我们的styles.scss文件中,有一个长长的// Optional Bootstrap CSS列表,其中包含所有组件的 Sass 部分。所以,这就是我们需要仔细考虑可以移除哪些部分文件的地方。在下面的代码片段中,您将看到长长的// Optional Bootstrap CSS列表,其中导入 Placeholder 和 Popover 组件 Sass 部分的行已被注释掉。您也可以选择删除这些行,但通过将它们注释掉,如果稍后添加这些组件到网站上,很容易取消注释它们,并且当 Sass 编译时,它们将自动被移除:
part-3/chapter-12/website/scss/style.scss
// Optional Bootstrap CSS
@import "../../../../bootstrap/scss/reboot";
@import "../../../../bootstrap/scss/type";
@import "../../../../bootstrap/scss/images";
@import "../../../../bootstrap/scss/containers";
@import "../../../../bootstrap/scss/grid";
@import "../../../../bootstrap/scss/tables";
@import "../../../../bootstrap/scss/forms";
@import "../../../../bootstrap/scss/buttons";
@import "../../../../bootstrap/scss/transitions";
@import "../../../../bootstrap/scss/dropdown";
@import "../../../../bootstrap/scss/button-group";
@import "../../../../bootstrap/scss/nav";
@import "../../../../bootstrap/scss/navbar";
@import "../../../../bootstrap/scss/card";
@import "../../../../bootstrap/scss/accordion";
@import "../../../../bootstrap/scss/breadcrumb";
@import "../../../../bootstrap/scss/pagination";
@import "../../../../bootstrap/scss/badge";
@import "../../../../bootstrap/scss/alert";
@import "../../../../bootstrap/scss/progress";
@import "../../../../bootstrap/scss/list-group";
@import "../../../../bootstrap/scss/close";
@import "../../../../bootstrap/scss/toasts";
@import "../../../../bootstrap/scss/modal";
@import "../../../../bootstrap/scss/tooltip";
// @import "../../../../bootstrap/scss/popover";
@import "../../../../bootstrap/scss/carousel";
@import "../../../../bootstrap/scss/spinners";
@import "../../../../bootstrap/scss/offcanvas";
// @import "../../../../bootstrap/scss/placeholders";
当我们编译 Sass 代码时,编译后的 CSS 样式表现在会稍微小一些,因为 Popover 和 Placeholder 组件的 CSS 已经被移除。
Sass 部分之间的依赖关系
在各种 Sass 部分文件之间存在一些依赖关系,因此简单地移除特定组件的文件可能并不容易。请确保仔细测试您的网站。
移除未使用的辅助器和实用工具
Bootstrap 5 的辅助器和实用工具是我们除了组件之外使用的,有时是在组件的特定代码中,有时是我们自己的 HTML 代码的一部分。因此,也可以考虑我们实际使用了哪些,并确保不包含我们未使用的那些。
移除未使用的辅助器
在我们为网站编写的代码中,我们使用了以下辅助器:比例、位置、视觉隐藏和拉伸链接。这些辅助器的 Bootstrap 5 代码通过以下代码导入到我们的style.scss文件中:
part-3/chapter-12/website/scss/style.scss
// Helpers
@import "../../../../bootstrap/scss/helpers";
这将导入包含对单个辅助器@import语句的_helpers.scss文件。该文件的内容如下:
part-3/chapter-12/website/bootstrap/scss/_helpers.scss
@import "helpers/clearfix";
@import "helpers/colored-links";
@import "helpers/ratio";
@import "helpers/position";
@import "helpers/stacks";
@import "helpers/visually-hidden";
@import "helpers/stretched-link";
@import "helpers/text-truncation";
@import "helpers/vr";
我们现在可能认为我们只需要取消注释我们不需要的辅助工具的@import语句,就像我们在上一节中对组件所做的那样。这在这里和现在会有效,但如果我们在以后选择更新 Bootstrap 5,我们的更改将会消失,因为_helpers.scss文件将被替换。这是因为这个文件是 Bootstrap 5 源代码的一部分,当你更新 Bootstrap 5 时会被替换。如果你知道你以后不会更新 Bootstrap 5,或者知道你会在更新后记得再次对_helpers.scss文件进行相同的编辑,你可以这样做:
part-3/chapter-12/website/bootstrap/scss/_helpers.scss
// @import "helpers/clearfix";
// @import "helpers/colored-links";
@import "helpers/ratio";
@import "helpers/position";
// @import "helpers/stacks";
@import "helpers/visually-hidden";
@import "helpers/stretched-link";
// @import "helpers/text-truncation";
// @import "helpers/vr";
但为了以更好的和更可维护的方式来做这件事,我们可以在styles.scss文件中更改我们的@import语句,只导入我们需要的单个辅助部分文件,而不是导入_helpers.scss文件。所以,我们将忽略那个文件(即使它是 Bootstrap 5 源代码的一部分),而是实现我们自己的导入助手的方式。
代码将看起来像这样:
part-3/chapter-12/website/scss/style.scss
// Helpers
// @import "../../../../bootstrap/scss/helpers/clearfix";
// @import "../../../../bootstrap/scss/helpers/colored-links";
@import "../../../../bootstrap/scss/helpers/ratio";
@import "../../../../bootstrap/scss/helpers/position";
// @import "../../../../bootstrap/scss/helpers/stacks";
@import "../../../../bootstrap/scss/helpers/visually-hidden";
@import "../../../../bootstrap/scss/helpers/stretched-link";
// @import "../../../../bootstrap/scss/helpers/text-truncation";
// @import "../../../../bootstrap/scss/helpers/vr";
我选择保留我们文件中的未使用导入,但将它们注释掉。这样,在需要时更容易取消注释它们,而且无论如何,在编译 Sass 时它们会被移除,因此不会占用任何空间。就像我们处理组件部分文件的导入一样。
移除未使用的工具
要移除未使用的工具,我们需要采取与组件和辅助工具不同的方法。我们现在需要使用我们之前在第六章中学习的工具 API。在 Bootstrap 5 的_utilities.scss文件中,我们看到总共定义了 80 个具有不同设置和值的工具类。对于每一个,我们都可以看到类或类前缀将是什么,我们可以使用这个来搜索我们的代码,看看我们实际上使用了哪些。如果我们这样做,我们会发现我们大约使用了其中的一半。为了更精确,我们需要移除以下 37 个未使用的工具类:
align, opacity, overflow, shadow, start, translate-middle, max-width, viewport-width, min-viewport-width, max-height, viewport-height, min-viewport-height, flex, flex-grow, flex-shrink, flex-wrap, gap, align-content, align-self, order, margin, margin-start, padding-x, padding-end, padding-start, font-family, word-wrap, text-opacity, bg-opacity, gradient, user-select, pointer-events, rounded-top, rounded-end, rounded-bottom, rounded-start, visibility
负边距工具(negative-margin、negative-margin-x、negative-margin-y、negative-margin-top、negative-margin-end、negative-margin-bottom和negative-margin-start)不包括在列表中,因为它们默认是禁用的,而且我们没有通过我们自己的 Sass 代码中的$enable-negative-margins选项启用它们。
为了移除所有未使用的工具,以便它们不会通过工具 API 生成,我们使用以下代码:
part-3/chapter-12/website/scss/_utilities.scss
// Remove unused utilities
$utilities: map-merge(
$utilities,
(
"align": null,
"opacity": null,
"overflow": null,
"shadow": null,
"start": null,
"translate-middle": null,
"max-width": null,
"viewport-width": null,
"min-viewport-width": null,
"max-height": null,
"viewport-height": null,
"min-viewport-height": null,
"flex": null,
"flex-grow": null,
"flex-shrink": null,
"flex-wrap": null,
"gap": null,
"align-content": null,
"align-self": null,
"order": null,
"margin": null,
"margin-start": null,
"padding-x": null,
"padding-end": null,
"padding-start": null,
"font-family": null,
"word-wrap": null,
"text-opacity": null,
"bg-opacity": null,
"gradient": null,
"user-select": null,
"pointer-events": null,
"rounded-top": null,
"rounded-end": null,
"rounded-bottom": null,
"rounded-start": null,
"visibility": null,
)
);
编译 Sass 代码后,生成的 CSS 文件(在扩展的 Sass 输出格式中)现在将减少 1,513 行,这相当于节省了 25,485 字节。
指定使用的工具
优化工具使用的一种另一种方法是指定正在使用的工具。在我们的项目中总共使用了 39 个工具,我们可以通过使用 Bootstrap 5 在 _functions.scss 文件中提供的 map-get-multiple() Sass 函数来生成这些工具。使用此函数,我们可以从 Sass 映射中获取多个键,从而按照以下方式覆盖 $utilities 变量:
SCSS
$utilities: map-get-multiple(
$utilities,
(
"float",
"display",
"position",
"top",
"bottom",
"end",
"border",
"border-top",
"border-end",
"border-bottom",
"border-start",
"border-color",
"border-width",
"width",
"height",
"flex-direction",
"justify-content",
"align-items",
"margin-x",
"margin-y",
"margin-top",
"margin-end",
"margin-bottom",
"padding",
"padding-y",
"padding-top",
"padding-bottom",
"font-size",
"font-style",
"font-weight",
"line-height",
"text-align",
"text-decoration",
"text-transform",
"white-space",
"color",
"background-color",
"rounded",
"utility",
)
);
无论你选择指定要删除的工具还是正在使用的工具,结果都将相同。
剪切使用中的工具
如果你想要走得更远,也可以剪切任何使用中的工具。我的意思是,通过编辑该工具的值来删除我们不使用的工具的任何变体。
假设我们想要编辑 text-align 工具,因为我们项目中只使用了 .text-center 类。所以,我们想要移除 .text-start 和 .text-end 变体,以及禁用此工具的响应式变体。为了实现这一点,我们可以使用以下代码:
SCSS
$utilities: map-merge(
$utilities,
(
"text-align": map-merge(
map-get($utilities, "text-align"),
( values: (
center: center,
),
responsive: false
),
),
)
);
现在,我们只生成 .text-center 类,这是我们用于文本对齐的唯一一个类。
或者,这也可以通过以下代码来完成,其中我们覆盖了文本对齐工具的代码,因此还必须指定 property 和 class:
SCSS
$utilities: map-merge(
$utilities,
(
"text-align": (
property: text-align,
responsive: false,
class: text,
values: (
center: center,
)
)
)
);
这只是一个例子。我没有在项目中使用这种方法来剪切使用中的工具,因为这是一项相当大的任务。但如果你走得更远,就有可能节省一些代码行和字节。
在下一节中,我们将使用 Node.js、npm 和 Laravel Mix 设置构建工具。我们将这样做是为了能够优化我们的 JavaScript 使用,并自动化 Sass 编译和一般压缩的任务。
使用 Node.js、npm 和 Laravel Mix 设置构建过程
在第二章**,使用和编译 Sass*中,我们已经学习了如何使用 Node.js 和 npm 设置一个脚本,该脚本将编译我们的 Sass 为 CSS。在这个设置中,我们将使用 Laravel Mix,它是围绕 Webpack 的包装器。简而言之,Webpack 是一个模块打包器,它为浏览器准备 JavaScript 和资源。通过使用 Laravel Mix,我们得到了一个简单的 API 来设置 Webpack 配置,而不需要任何先前的 Webpack 经验。
如果你还没有安装 Node.js,那么请返回并查看第二章和编译 Sass部分。现在,这里有一个使用 Node.js 和 npm 设置 Laravel Mix 的逐步指南。这将最终生成一个 package.json 文件、一个 Laravel Mix 配置文件、一个文件夹和一些空文件。
跳过设置 Laravel Mix
如果你想,你可以选择跳过 Laravel Mix 的手动设置,直接使用本书提供的 Laravel Mix 模板中的相关代码。然后,简单地进入下一节。
在我们开始设置 Laravel Mix 之前,我们必须打开终端(Mac)或命令提示符(Windows)并导航到我们的项目文件夹。然后,我们可以按照以下八个步骤进行操作:
-
使用默认设置生成一个空的 npm 项目:
npm init -y -
安装 Bootstrap 5 的最新版本:
npm install bootstrap@5.2.0 --save-dev
使用 --save-dev 来指定这是一个开发依赖项。如果你想安装其他版本,请更改版本号。
-
安装 Popper,它是 Dropdown、Popover 和 Tooltip 组件的依赖项:
npm install @popperjs/core --save-dev -
安装 Laravel Mix:
npm install laravel-mix --save-dev -
在项目的根目录中创建
webpack.mix.js文件。这是 Laravel Mix 的配置文件。 -
在项目的根目录中,创建一个包含空
js和scss文件夹的src文件夹。在js文件夹中创建script.js文件,在scss文件夹中创建style.scss文件。文件和文件夹结构应如下所示:src |- js |- script.js |- scss |- style.scss
我们将在这些文件中稍后添加一些代码。
-
将以下代码添加到配置文件(
webpack.mix.js)中,以导入mix并定义我们的构建:let mix = require('laravel-mix'); mix.js('src/js/script.js', 'js/').sass( 'src/scss/style.scss', 'css/');
Laravel Mix 现在已被指示执行以下操作:
-
将
src/js/script.js中的 JavaScript 打包并输出到js文件夹。 -
编译
src/scss/style.scss中的 Sass 并将其输出到css文件夹。 -
运行以下命令来安装额外的依赖项:
npx mix
此命令通常只需运行一次。
使用 Laravel Mix 模板
如果您没有按照手动步骤设置 Laravel Mix,您也可以从 part-3/chapter-12/laravel-mix/template 文件夹中获取 Laravel Mix 模板。在这种情况下,您只需将模板文件夹的内容放置到您的项目文件夹中,并运行以下命令:
npm install
这将安装 Bootstrap 5、Popper 和 Laravel Mix,以及所有依赖项。您不需要运行 npx mix 命令来安装额外的依赖项。
使用 Laravel Mix
我们项目中的代码现在应该看起来像这样:
src
|- js
|- script.js
|- scss
|- style.scss
package-lock.json
package.json
webpack.mix.js
请注意,我们还没有在 script.js 和 style.scss 文件中放入任何代码,也没有向项目中添加任何 HTML 文件或其他资源。我们将在稍后进行。首先,让我们看看两个最有用的命令。
触发 Webpack 构建,我们在 webpack.mix.js 文件中定义了它,我们只需运行以下命令:
npx mix
这将现在编译文件并构建包。
要监视文件系统中的更改并自动重新编译文件和重新构建包,我们可以使用以下命令:
npx mix watch
每次我们在项目文件夹中的 JavaScript 或 Sass 文件保存更改时,Webpack 都会运行。
script.js 和 style.scss 文件中还没有添加任何代码
由于我们还没有在 src 文件夹中的 script.js 和 style.scss 文件中添加任何代码,Laravel Mix 的命令目前不会产生任何结果。我们现在将这样做。
将网站代码添加到构建过程中
由于我们的项目与 Laravel Mix 的使用方式不兼容,我们必须对其进行一些更改。因此,我们不会在 part-3/chapter-12/website 中的现有项目中做出更改,而是将其复制到 part-3/chapter-12/laravel-mix/setup 并在那里进行更改。请注意,本节中描述的所有更改已应用于 GitHub 上的代码。
为了重构和更新我们的项目,我们需要采取以下步骤:
src文件夹:
首先,我们必须将我们的 js 和 scss 文件夹移动到新的 src 文件夹中,并删除 bootstrap.bundle.min.js 文件。Bootstrap 5 JavaScript 代码将由 Laravel Mix 编译和打包,然后放置在另一个文件夹中。
- 更新 HTML:
由于我们在上一步中已删除 bootstrap.bundle.min.js 文件,我们现在可以从所有 HTML 文件中删除以下代码行:
HTML
<script src="img/bootstrap.bundle.min.js"></script>
然后,在之前仅包含 bootstrap.bundle.min.js 文件而没有 script.js 文件的文件中,我们必须添加此文件,以便最终所有 HTML 页面都只包含以下 script 标签:
<script src="img/script.js"></script>
因此,每个 HTML 文件的底部部分应该看起来像这样,但有少数例外:
</footer>
<script src="img/script.js"></script>
</body>
</html>
- 更新 Sass:
现在,我们需要更新 style.scss 文件中 Bootstrap 5 Sass 部分的导入文件路径。我们需要将 ../bootstrap/scss/ 替换为 ~bootstrap/scss/(或简单地用 ../ 替换 ~),以确保直接从 node_modules 文件夹获取源代码。波浪字符 ~ 是对该文件夹的引用。
我们 style.scss 文件的上部现在应该看起来像这样:
part-3/chapter-12/laravel-mix/website/src/scss/style.scss
// Required
@import "~bootstrap/scss/functions";
// Default variable overrides
@import "default-variable-overrides";
// Required
@import "~bootstrap/scss/variables";
// Variable value using existing variable
@import "variable-value-using-variable";
// Required
@import "~bootstrap/scss/maps";
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/root";
我们将保持其余的 Sass 文件不变。
- 更新 JavaScript:
当我们通过 <script> 标签加载 Bootstrap 5 时,我们在初始化 JavaScript 组件时使用 bootstrap 命名空间,如下所示:
JavaScript
new bootstrap.component
为了将 Bootstrap 5 JavaScript 源代码导入以使其与我们的当前 JavaScript 代码兼容,我们必须在 script.js 文件的顶部以以下方式执行:
part-3/chapter-12/laravel-mix/setup/src/js/script.js
import * as bootstrap from 'bootstrap';
这将导入所有 Bootstrap 5 JavaScript 源文件,这与我们之前在 <script> 标签中使用 bootstrap.bundle.min.js 文件时的情况类似。
现在,为了实际触发 Webpack 构建、编译 Sass 和打包 JavaScript,我们可以使用之前的 Laravel Mix 命令运行一次:
npx mix
或者,我们可以使用以下命令在每次保存项目文件夹中 JavaScript 或 Sass 文件更改时运行它:
npx mix watch
我们现在已经学会了如何使用 Node.js、npm 和 Laravel Mix 设置构建过程。然而,尽管我们没有使用所有 JavaScript 代码,但我们仍然导入了所有 JavaScript 代码。接下来,我们将看到如何优化 JavaScript 导入。
使用模块打包器优化 JavaScript
当使用模块打包器时,我们可以优化我们对 JavaScript 文件的使用。我们不必像之前那样导入所有 Bootstrap 5 的 JavaScript 源文件,而只需导入我们需要的文件。
在 Bootstrap 5 的源代码中,我们有一个 bootstrap/js/dist 文件夹,其中包含单个 JavaScript 组件的源代码,以及 base-component.js 文件和 dom 文件夹,其中包含一些与操作 DOM(页面文档对象模型)相关的一般代码。
我们可能会想象,我们只需在我们的 HTML 中的 <script> 标签中添加这些文件之一,如下所示:
HTML
<script src="img/modal.js"></script>
然而,这不会起作用。我们将在浏览器控制台中收到错误。我们必须在我们的 script.js 文件中引用这些文件并使用模块打包器。
例如,如果我们只导入 bootstrap/js/dist/modal.js 文件,它也将导入 bootstrap/js/dist/base-component.js 文件以及 bootstrap/js/dist/dom 文件夹中所有与 DOM 相关的文件。
如果我们只导入 bootstrap/js/dist/tooltip.js 文件,它也将导入 bootstrap/js/dist/base-component.js 文件,bootstrap/js/dist/dom 文件夹中所有与 DOM 相关的文件,以及 Popper npm 包的所有必要文件,因为工具提示组件依赖于这个库进行定位。
在我们继续之前,请注意,我们不会对 part-3/chapter-12/laravel-mix/setup 中的代码进行更多修改,而是将其复制到 part-3/chapter-12/laravel-mix/optimize-js 并在那里进行修改。请注意,本节中描述的所有更改已应用于 GitHub 上的代码。
在我们的网站上,我们使用所有 JavaScript 组件,除了按钮、弹出框和滚动位置(然而,我们仍然使用按钮作为使用 HTML 和 CSS 的常规组件)。现在,为了优化 JavaScript 文件的使用,我们将向我们的 script.js 文件添加以下代码行,仅包括我们实际使用的组件:
part-3/chapter-12/laravel-mix/optimize-js/src/js/script.js
import Alert from 'bootstrap/js/dist/alert';
import Carousel from 'bootstrap/js/dist/carousel';
import Collapse from 'bootstrap/js/dist/collapse';
import Dropdown from 'bootstrap/js/dist/dropdown';
import Modal from 'bootstrap/js/dist/modal';
import Offcanvas from 'bootstrap/js/dist/offcanvas';
import Tab from 'bootstrap/js/dist/tab';
import Toast from 'bootstrap/js/dist/toast';
import Tooltip from 'bootstrap/js/dist/tooltip';
如前所述,当我们通过 <script> 标签加载 Bootstrap 5 时,我们在初始化 JavaScript 组件时使用 bootstrap 命名空间,如下所示:
JavaScript
new bootstrap.component
由于我们现在正在使用打包器,window 对象将不会被定义,因此我们必须以以下方式初始化组件:
JavaScript
new component
因此,我们需要对我们的 script.js 文件进行一些修改。我们需要将所有使用的地方的 new bootstrap.[component] 代码替换为 new [component]。例如,在初始化所有工具提示的代码中,我们必须进行以下更改:
part-3/chapter-12/laravel-mix/optimize-js/src/js/script.js
const tooltipTriggerElements =
document.querySelectorAll('[data-bs-toggle="tooltip"]');
for (let i = 0; i < tooltipTriggerElements.length; i++) {
new bootstrap.Tooltip(tooltipTriggerElements[i])
}
现在,我们可以再次运行之前提到的相同的 Laravel Mix 命令。
请注意,我们还必须运行以下命令:
npm install
如果它还没有运行过。此命令将创建 node_modules 文件夹并下载所有必要的依赖项(包括 Bootstrap 5 的源代码)到那里。
压缩我们的编译 CSS 和打包 JavaScript
为了进一步优化我们的代码,我们希望压缩编译后的 CSS 和打包的 JavaScript。我们可以通过运行以下命令使用 Laravel Mix 来实现:
npx mix --production
--production 标志用于指示我们想要压缩编译和打包的文件。
摘要
我们现在已经学会了如何优化编译后的 Bootstrap 5 CSS 和 JavaScript 代码。首先,我们学习了如何通过仅包含我们实际使用的 Bootstrap 5 Sass 部分并移除所有未使用的辅助工具和实用工具来优化我们的样式表。然后,我们学习了如何使用 Node.js、npm 和 Laravel Mix 设置构建过程来自动化一些任务,这有助于我们仅打包我们的组件实际使用的 JavaScript,并压缩我们的编译 CSS 和打包 JavaScript。
尽管本章中描述的方法和技术不会改变网站的外观和感觉,但它们将优化您的最终代码,从而为用户提供更好的性能和更快的加载时间。
在本书中,我们学习了以各种新的方式使用 Bootstrap 5。从只知道关于默认样式下各种 Bootstrap 5 组件的 HTML 结构和类名,我们学习了如何更改全局选项和调色板,如何理解并导航 Sass 源代码,如何使用 Sass 变量自定义各种 Bootstrap 5 元素,以及如何使用强大的实用 API。在此基础上,我们还学习了如何使用更高级的 Sass、CSS 和 JavaScript 功能与 Bootstrap 5 结合,最后学习了如何优化编译后的 CSS 和 JavaScript(包括使用模块打包器)。现在,作为 Bootstrap 5 开发者,我们已经具备了解决更高级任务和更富有创意地使用 Bootstrap 5 源代码的能力。
感谢阅读!


浙公网安备 33010602011771号