关于 Sass
Sass 是一种 CSS 预处理器,它为标准 CSS 添加了变量、嵌套、混入和函数等功能。你编写 .scss 文件,进行编译,输出的是浏览器可以理解的普通 CSS。如果你是 Sass 新手,可以查看 Sass 文档 学习基础知识。
Bootstrap 是用 Sass 编写的。我们的源 .scss 文件使用 Sass map来定义设计标记,使用混入 (mixins) 生成重复的 CSS 模式,并使用 @use/@forward 模块系统来组织所有内容。编译后,这些 Sass 文件会生成用于驱动每个 Bootstrap 组件和工具的 CSS。这让你可以覆盖标记值、移除未使用的组件,或者用你自己的扩展来扩展系统。如果你不需要这种级别的控制,你可以完全跳过 Sass,而是在运行时通过 CSS 自定义属性 来进行自定义。
刚开始使用 Sass 和 Bootstrap? 从我们的 npm 指南开始,按照步骤进行设置,或者查看我们的示例仓库,获取可直接使用的入门项目。
文件结构
尽可能避免修改 Bootstrap 的核心文件。对于 Sass 来说,这意味着创建你自己的样式表来导入 Bootstrap,这样你就可以对其进行修改和扩展。假设你使用的是像 npm 或 yarn 这样的包管理器,你的文件结构将如下所示:
your-project/
├── scss/
│ └── custom.scss
└── node_modules/
│ └── bootstrap/
│ ├── js/
│ └── scss/
└── index.html
如果你已经下载了我们的源文件并且没有使用包管理器,你将需要手动创建一个类似的结构,并将 Bootstrap 的源文件与你自己的文件分开。
your-project/
├── scss/
│ └── custom.scss
├── bootstrap/
│ ├── js/
│ └── scss/
└── index.html
导入
在你的 custom.scss 中,你将导入 Bootstrap 的源 Sass 文件。你有两个选项:包含所有 Bootstrap,或者只选择你需要的部分。我们鼓励后者,但请注意我们的组件之间存在一些要求和依赖。你还需要为我们的插件包含一些 JavaScript。
// Custom.scss
// Option A: Include all of Bootstrap
@use "../node_modules/bootstrap/scss/bootstrap";
// Then add additional custom code here
// Custom.scss
// Option B: Include parts of Bootstrap
// 1. Include root first (configuration, colors, tokens, and CSS layers)
@use "../node_modules/bootstrap/scss/root";
// 2. Include any other partials as needed
@use "../node_modules/bootstrap/scss/content";
@use "../node_modules/bootstrap/scss/layout";
@use "../node_modules/bootstrap/scss/forms";
@use "../node_modules/bootstrap/scss/buttons";
// 3. Components
@use "../node_modules/bootstrap/scss/alert";
@use "../node_modules/bootstrap/scss/card";
// ...
// 4. Helpers and utilities
@use "../node_modules/bootstrap/scss/helpers";
@use "../node_modules/bootstrap/scss/utilities/api";
// 5. Add additional custom code here
在设置完成后,你可以开始修改你custom.scss中的任何 Sass 令牌映射。我们建议使用我们的bootstrap.scss文件中的完整导入堆栈作为起点。
@forward "banner";
// Configuration variables and maps, such as $utilities. Forwarding config makes
// them configurable from this entrypoint with `@use ... with (...)`. Emits no CSS.
@forward "config";
@forward "colors";
// Theme color maps ($theme-colors, $theme-bgs, etc.). Forwarding makes them
// configurable from this entrypoint with `@use ... with (...)`. Emits no CSS.
@forward "theme";
// Global CSS variables, layer definitions, and configuration
@forward "root";
// Subdir imports
@forward "content";
@forward "layout";
@forward "forms";
@forward "buttons";
// Components
@forward "accordion";
@forward "alert";
@forward "avatar";
@forward "badge";
@forward "breadcrumb";
@forward "chip";
@forward "card";
@forward "carousel";
@forward "datepicker";
@forward "dialog";
@forward "menu";
@forward "list-group";
@forward "nav";
@forward "nav-overflow";
@forward "navbar";
@forward "drawer";
@forward "pagination";
@forward "placeholder";
@forward "popover";
@forward "progress";
@forward "spinner";
@forward "stepper";
@forward "toasts";
@forward "tooltip";
@forward "transitions";
// Helpers
@forward "helpers";
// Utilities
@forward "utilities/api";
编译
为了在浏览器中将自定义 Sass 代码作为 CSS 使用,你需要一个 Sass 编译器。Sass 以 CLI 包的形式提供,但你也可以使用其他构建工具如 Gulp 或 Webpack 进行编译,或者使用 GUI 应用程序。一些 IDE 也内置了 Sass 编译器,或者可以通过可下载的扩展来使用。
我们喜欢使用 CLI 来编译我们的 Sass,但你可以使用任何你喜欢的方法。从命令行运行以下命令:
# Install Sass globally
npm install -g sass
# Watch your custom Sass for changes and compile it to CSS
sass --watch ./scss/custom.scss ./css/custom.css
在 sass-lang.com/install 和 使用 VS Code 编译 中了解更多关于你的选项。
使用 Bootstrap 与其他构建工具? 可以考虑阅读我们关于使用 Webpack、Parcel 或 Vite 进行编译的指南。我们在 GitHub 上的示例仓库 也有可用于生产的演示。
包括
一旦你的 CSS 被编译,你可以将其包含在你的 HTML 文件中。在index.html内,你需要包含编译后的 CSS 文件。如果你更改了编译后的 CSS 文件的路径,请务必更新该路径。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom Bootstrap</title>
<link href="/css/custom.css" rel="stylesheet">
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
代币架构
Bootstrap v6 使用基于 CSS 自定义属性的分层令牌系统。Sass map在编译时定义令牌,并且从这些映射生成 CSS 自定义属性以供运行时使用。
各层,从最低到最高级:
颜色刻度 (
_colors.scss) — 在oklch()中定义的基色变量使用color-mix()生成完整的颜色步进刻度(025–975)作为 CSS 自定义属性。例如,--blue-500、--red-200、--gray-900。主题颜色 (
_theme.scss) —$theme-colors映射定义了语义颜色角色,如primary、success和danger。每个主题颜色都是一个嵌套映射,包含子键:base、text、text-emphasis、bg、bg-subtle、bg-muted、border、focus-ring和contrast。全局令牌 (
_theme.scss和_root.scss) — 背景($theme-bgs)、前景($theme-fgs)和边框($theme-borders)的语义令牌与$root-tokens映射一起定义,该映射将所有内容汇总为:rootCSS 自定义属性。组件令牌(例如,
_alert.scss)— 每个组件定义自己的$*-tokens映射(例如$alert-tokens),并作为作用于该组件类的 CSS 自定义属性输出。
令牌默认值
Bootstrap 中的每个令牌映射都包括 !default 标志,允许你在加载 Bootstrap 文件之前覆盖值。由于 Bootstrap 使用 Sass 模块(@use/@forward),你可以覆盖 !default 使用的变量 with () 语法。对于 CSS 自定义属性标记,你有两种自定义路径:
- 在编译时 — 覆盖生成 CSS 自定义属性的 Sass map。
- 在运行时 — 直接在你的样式表中覆盖 CSS 自定义属性,无需 Sass。
编译时覆盖
要在编译时覆盖令牌值,在导入 Bootstrap 时使用 @use ... with ()。你只需包括你想要更改的键 —— Bootstrap 使用 defaults() 函数将你的覆盖与其默认值合并,因此所有其他令牌保持不变。
@use "../node_modules/bootstrap/scss/bootstrap" with (
$root-tokens: (
--border-radius: .25rem,
--spacer: 1.5rem,
),
$alert-tokens: (
--alert-padding-x: 2rem,
--alert-border-radius: 1rem,
)
);
在底层,每个令牌映射使用两步模式:
$alert-tokens: () !default;
$alert-tokens: defaults(
(
// Default tokens here
),
$alert-tokens
);
() !default 声明接收你的 with() 覆盖。然后 defaults() 将你的条目合并到内置默认值之上,因此未指定的键将保留其原始值。任何设置为 null 的键将完全从映射中移除,让你可以删除不需要的令牌。
运行时覆盖
因为令牌作为 CSS 自定义属性输出,你可以在 CSS 中直接覆盖它们,而无需任何 Sass 编译:
:root {
--border-radius: .25rem;
--primary-base: oklch(55% 0.25 260);
--bg-body: #f8f9fa;
}
你也可以将覆盖范围限定到特定组件:
.alert {
--alert-padding-x: 2rem;
--alert-padding-y: 1.5rem;
--alert-border-radius: 1rem;
}
使用 Bootstrap npm 入门项目! 前往 Sass & JS 示例 模板仓库,了解如何在自己的 npm 项目中构建和定制 Bootstrap。包括 Sass 编译器、Autoprefixer、Stylelint、PurgeCSS 以及 Bootstrap 图标。
映射和循环
Bootstrap 包含几个 Sass map,用于生成相关的 CSS 自定义属性家族。这些映射都包含 !default 标志,并且可以被覆盖。
主题颜色映射
$theme-colors 地图定义了语义颜色调色板。每个条目都是一个嵌套地图,包含 base、text、bg、border 等子键。完整的地图、子键参考及使用示例,请参见 主题文档。
要在编译时添加、修改或删除主题颜色,请配置 $theme-colors 通过主要入口点与 @use ... with (). defaults() 将你的地图合并到内置内容之上,这样标准主题保持不变,你只添加所需的内容:
@use "../node_modules/bootstrap/scss/bootstrap" with (
$theme-colors: (
"brand": (
"base": var(--indigo-500),
"fg": light-dark(var(--indigo-600), var(--indigo-400)),
"fg-emphasis": light-dark(var(--indigo-800), var(--indigo-300)),
"bg": var(--indigo-500),
"bg-subtle": light-dark(var(--indigo-100), var(--indigo-900)),
"bg-muted": light-dark(var(--indigo-200), var(--indigo-800)),
"border": light-dark(var(--indigo-300), var(--indigo-600)),
"focus-ring": light-dark(color-mix(in oklch, var(--indigo-500) 50%, var(--bg-body)), color-mix(in oklch, var(--indigo-500) 75%, var(--bg-body))),
"contrast": var(--white)
)
)
);
每个主题颜色都是一个嵌套映射,因此合并仅为一层深度。要更改内置主题的某个子键,请传递该主题的整个子映射。部分子映射会替换主题的其他子键,而不是与它们合并。要删除主题,请将其键设置为null。
全球代币映射
背景($theme-bgs)、前景($theme-fgs)和边框($theme-borders)令牌映射定义语义层颜色。这些内容也在 主题文档 中有所介绍。
根代币 ($root-tokens)
$root-tokens 地图汇总了全球设计令牌,如字体、间距、边框和表单变量。主题颜色、背景色、前景色和边框令牌在输出前会合并到其中。
// stylelint-disable @stylistic/value-list-max-empty-lines, @stylistic/function-max-empty-lines, custom-property-no-missing-var-function
// stylelint-disable-next-line scss/dollar-variable-default
$root-tokens: defaults(
(
--black: #{$black},
--white: #{$white},
--gradient: #{$gradient},
// scss-docs-start root-body-variables
// The stack omits system-ui. It resolves to the user interface font of the
// locale, which shows non-Latin text incorrectly. See twbs/bootstrap#42703.
--body-font-family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
--body-font-size: 1rem,
--body-font-weight: var(--font-weight-normal),
--body-line-height: 1.5,
// scss-docs-end root-body-variables
--heading-color: inherit,
--hr-border-color: var(--border-color),
--link-color: light-dark(var(--primary-base), var(--primary-fg)),
--link-decoration: underline,
--link-underline-offset: .2em,
--link-hover-color: color-mix(in oklch, var(--link-color) 90%, #000),
--font-mono: "ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Monaco, 'Cascadia Mono', Consolas, 'Liberation Mono', monospace",
--code-font-size: 95%,
--code-color: var(--fg-2),
// scss-docs-start root-border-var
--border-width: #{$border-width},
--border-width-keyline: .5px,
--border-style: #{$border-style},
--border-color: light-dark(var(--gray-200), var(--gray-700)),
--border-color-translucent: color-mix(in oklch, var(--fg-body) 15%, transparent),
// scss-docs-end root-border-var
// scss-docs-start root-box-shadow-variables
// --box-shadow* tokens are generated below (see root-box-shadow-loop) from
// the shared $shadows map in scss/_config.scss, which reads these two.
--shadow-color: #000,
--shadow-strength: 1,
// scss-docs-end root-box-shadow-variables
// scss-docs-start root-transition-variables
// Shared easing curve for overlay components (dialog, drawer, menu)
--transition-timing-overlay: cubic-bezier(.22, 1, .36, 1),
// scss-docs-end root-transition-variables
--spacer: #{$spacer},
// scss-docs-start root-focus-variables
--focus-ring-width: 3px,
--focus-ring-offset: 1px,
--focus-ring-color: var(--primary-focus-ring),
--focus-ring: var(--focus-ring-width) solid var(--focus-ring-color),
// scss-docs-end root-focus-variables
// scss-docs-start root-form-variables
--control-checked-bg: var(--primary-base),
--control-checked-border-color: var(--control-checked-bg),
--control-active-bg: var(--primary-base),
--control-active-border-color: var(--control-active-bg),
--control-disabled-bg: var(--bg-3),
--control-disabled-opacity: .65,
// Shared motion for checkbox/radio marks; slight overshoot so the mark pops in
--control-transition-duration: .15s,
--control-transition-timing: cubic-bezier(.34, 1.56, .64, 1),
--btn-input-fg: var(--fg-body),
--btn-input-bg: var(--bg-body),
--btn-input-gap: .375rem,
--btn-input-min-height: 2.375rem,
--btn-input-padding-y: .375rem,
--btn-input-padding-x: .75rem,
--btn-input-font-size: var(--body-font-size),
--btn-input-font-weight: var(--font-weight-normal),
--btn-input-line-height: var(--body-line-height),
--btn-input-border-radius: var(--radius-5),
--btn-input-xs-gap: var(--spacer-1),
--btn-input-xs-min-height: 1.5rem,
--btn-input-xs-padding-y: .125rem,
--btn-input-xs-padding-x: .5rem,
--btn-input-xs-font-size: var(--font-size-xs),
--btn-input-xs-line-height: 1.125,
--btn-input-xs-border-radius: var(--radius-5),
--btn-input-sm-gap: .375rem,
--btn-input-sm-min-height: 2rem,
--btn-input-sm-padding-y: .25rem,
--btn-input-sm-padding-x: .625rem,
--btn-input-sm-font-size: var(--font-size-sm),
--btn-input-sm-line-height: var(--line-height-sm),
--btn-input-sm-border-radius: var(--radius-5),
--btn-input-lg-gap: .375rem,
--btn-input-lg-min-height: 2.75rem,
--btn-input-lg-padding-y: .5rem,
--btn-input-lg-padding-x: 1rem,
--btn-input-lg-font-size: var(--font-size-md),
--btn-input-lg-line-height: var(--line-height-md),
--btn-input-lg-border-radius: var(--radius-7),
// scss-docs-end root-form-variables
),
$root-tokens
);
// stylelint-enable @stylistic/value-list-max-empty-lines, @stylistic/function-max-empty-lines, custom-property-no-missing-var-function
所有根令牌都作为 CSS 自定义属性输出到 :root:
// Generate semantic theme colors
@each $color-name, $color-map in $theme-colors {
@each $key, $value in $color-map {
$root-tokens: map.set($root-tokens, --#{$color-name}-#{$key}, $value);
}
}
// Generate background tokens
@each $key, $value in $theme-bgs {
$root-tokens: map.set($root-tokens, --bg-#{$key}, $value);
}
// Generate foreground tokens
@each $key, $value in $theme-fgs {
$root-tokens: map.set($root-tokens, --fg-#{$key}, $value);
}
// Generate border tokens
@each $key, $value in $theme-borders {
$root-tokens: map.set($root-tokens, --border-#{$key}, $value);
}
组件令牌
每个组件定义自己的令牌映射,这些映射会作为 CSS 自定义属性输出,并限定在组件的类中。这使得组件自包含且易于定制。
这是一个警告组件示例:
// stylelint-disable-next-line scss/dollar-variable-default
$alert-tokens: defaults(
(
--alert-gap: var(--spacer-3),
--alert-bg: var(--bg-1),
--alert-padding-x: var(--spacer),
--alert-padding-y: var(--spacer),
--alert-color: inherit,
--alert-border-color: var(--border-color),
--alert-border-radius: var(--radius-7),
--alert-link-color: inherit,
--alert-transition-property: "opacity",
--alert-transition-duration: .15s,
--alert-transition-timing: linear,
--hr-border-color: var(--theme-border, var(--alert-border-color)),
),
$alert-tokens
);
令牌输出在 .alert 使用该类 tokens() 混入:
.alert {
@include tokens($alert-tokens);
padding: var(--alert-padding-y) var(--alert-padding-x);
color: var(--alert-color);
background-color: var(--alert-bg);
border: var(--alert-border);
// ...
}
覆盖 Sass 令牌
使用 with () 在编译时覆盖特定组件的令牌值。你的覆盖值将与默认值合并,因此你只需要指定想要更改的键:
@use "../node_modules/bootstrap/scss/bootstrap" with (
$alert-tokens: (
--alert-padding-x: 2rem,
--alert-bg: var(--bg-2),
--alert-border-radius: 0,
)
);
这适用于每个组件:$card-tokens、$button-tokens、$menu-tokens、$nav-tokens,依此类推 —— 任何 $*-tokens 映射都通过相同的合并模式支持部分覆盖。
移除值为null的令牌
将任何映射键设置为 null 可以完全移除它。defaults() 函数会在使用映射之前去除空值条目,因此不会为这些键生成任何 CSS:
@use "../node_modules/bootstrap/scss/bootstrap" with (
$alert-tokens: (
--alert-margin-bottom: null,
)
);
覆盖 CSS 令牌
你也可以直接覆盖 CSS 自定义属性,而无需使用 Sass:
.alert {
--alert-padding-x: 2rem;
--alert-bg: var(--bg-2);
--alert-border-radius: 0;
}
尺码表
除了令牌映射之外,Bootstrap 还使用尺寸映射来生成像这样的尺寸变体类 .btn-sm, .btn-lg, .form-control-sm,等等。这些使用相同的 defaults() 支持相同的覆盖和移除模式的功能。
尺寸映射接受一个简单的尺寸名称列表:
$button-sizes: () !default;
$button-sizes: defaults(
("xs", "sm", "lg"),
$button-sizes
);
然后循环从每个尺寸名称中获取 CSS 自定义属性值:
@each $size, $_ in $button-sizes {
.btn-#{$size} {
--btn-min-height: var(--btn-input-#{$size}-min-height);
--btn-padding-y: var(--btn-input-#{$size}-padding-y);
// ...
}
}
要移除一个尺寸,请将其键设置为 null 通过 with():
@use "../node_modules/bootstrap/scss/bootstrap" with (
$button-sizes: ("xs": null),
);
变体地图
一些组件使用变体映射来生成样式变体。例如,$button-variants 定义了 solid、outline、subtle 和 text 按钮样式。这些也由 defaults() 处理,并支持 null 移除:
@use "../node_modules/bootstrap/scss/bootstrap" with (
$button-variants: (
"text": null,
"subtle": null,
),
);
这会从编译后的 CSS 中移除 .btn-text 和 .btn-subtle 类,同时保持 .btn-solid 和 .btn-outline 完好无损。
必需的键
Bootstrap 假设 Sass map中存在一些特定的键,因为我们会自己使用和扩展这些键。当你自定义包含的映射时,可能会遇到正在使用特定 Sass map键的错误。
对于 $theme-colors,primary、success 和 danger 键是链接、按钮和表单状态所必需的。替换这些键的值应该不会有问题,但移除它们可能会导致 Sass 编译问题。
功能
默认值
defaults() 函数是 Bootstrap 定制系统的核心。它将用户的覆盖合并到内置的默认令牌之上,并从结果中删除任何 null 条目。每个令牌映射、尺寸映射和变体映射都使用它:
@function defaults($defaults, $overrides) { ... }
它接受地图或列表作为第一个参数。列表会被自动转换为带有true值的地图,这就是像$button-sizes这样的尺寸地图如何使用干净的("xs", "sm", "lg")语法工作的方式。
defaults() 是在特定选择器上使用 tokens() mixin 生成的。
颜色对比
为了满足 网页内容无障碍指南(WCAG) 的对比度要求,作者 必须 提供最低 文字颜色对比度为 4.5:1,以及最低 非文字颜色对比度为 3:1,几乎没有例外。
为了帮助实现这一点,我们在 Bootstrap 中加入了 color-contrast 函数。它使用 WCAG 对比度比率算法,根据 相对亮度 在 sRGB 颜色空间中计算对比度阈值,以根据指定的基础颜色自动返回浅色 (#fff)、深色 (#212529) 或黑色 (#000) 对比颜色。这个函数对于生成多个类的 mixin 或循环尤其有用。
例如,要从我们的$theme-colors地图生成颜色样本:
@each $color, $value in $theme-colors {
.swatch-#{$color} {
color: color-contrast(map.get($value, "base"));
}
}
转义 SVG
我们使用 escape-svg 函数来转义 <、> 和 # 字符用于 SVG 背景图像。使用 escape-svg 函数时,数据 URI 必须加引号。
// Input — an inline SVG with special characters
$icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#00000080' stroke-width='2' d='m2 5 6 6 6-6'/></svg>");
// After escape-svg(), the <, >, and # characters are percent-encoded
// so the data URI works reliably in CSS (e.g. as a mask-image or background-image)
.element {
mask-image: escape-svg($icon);
}
地图助手
我们包含了几个用于处理映射的 Sass 函数,超出了 Sass 原生提供的功能。
| 功能 | 描述 |
|---|---|
map-merge-multiple($maps...) | 将任意数量的映射合并为一个,从左到右处理它们。 |
map-get-multiple($map, $values) | 返回一个映射的子集,仅包含$values中列出的键。 |
map-get-nested($map, $nested-key) | 从每个嵌套的映射条目中提取单个属性,返回一个扁平映射。 |
map-merge-multiple($maps...)
@function map-merge-multiple($maps...) { ... }
// Example: combine spacers, negative spacers, and auto into a single values map
values: map-merge-multiple($spacers, $negative-spacers, (auto: auto))
map-get-multiple($map, $values)
@function map-get-multiple($map, $values) { ... }
// Example: extract only the flex and order utilities
$utilities: map-get-multiple(
$utilities,
("flex", "flex-direction", "flex-grow", "order")
);
map-get-nested($map, $nested-key)
@function map-get-nested($map, $nested-key) { ... }
// Example: pull just the "font-size" value from each entry in $font-sizes
values: map-get-nested($font-sizes, "font-size")
// Returns: ("xs": clamp(...), "sm": clamp(...), ...)
negativify-map($map)
将一个映射转换为其负数变体,通过在每个键前加上 n 并对值取负。等于 0 的键将被跳过。当自定义工具需要负值时使用它。
@function negativify-map($map) { ... }
// Example: generate negative values from part of the spacer scale
$custom-spacers: (0: 0, 1: .25rem, 2: .375rem, 3: .5rem);
$negative-spacers: negativify-map($custom-spacers);
// Returns: ("n1": -.25rem, "n2": -.375rem, "n3": -.5rem)
主题颜色值
这 theme-color-values($key) 函数在 scss/_theme.scss 从每个条目中提取特定的子键 $theme-colors 映射,返回一个将颜色名称映射到数值的扁平映射。由于每个主题颜色都是一个带有子键的嵌套映射,例如 base, text, bg, border等等,这个功能让你一次性获取所有颜色中的某个子键。它为大多数与颜色相关的工具提供支持 _utilities.scss:
// In _utilities.scss — generate .focus-ring-{color} classes
"focus-ring": (
property: --focus-ring-color,
class: focus-ring,
values: theme-color-values("focus-ring"),
),
// Merge theme color backgrounds with semantic border tokens for .border-{color} classes
"border-color": (
property: (
"--border-color": null,
"border-color": var(--border-color)
),
class: border,
values: map.merge(theme-color-values("bg"), $theme-borders),
),
主题不透明度值
这 theme-opacity-values($color-var, $opacities) 函数在 scss/_theme.scss 使用 CSS 自定义属性生成不透明度变体的映射 color-mix()。那 $opacities 参数默认为 $util-opacity (从10到100,步长为10)。在 100,它直接返回变量;对于所有其他步骤,它将变量进行混合 transparent:
// In _utilities.scss — generate .border-{opacity} classes
"border-opacity": (
class: border,
property: border-color,
values: theme-opacity-values(--border-color)
),
// Generate .fg-{opacity} classes
"fg-opacity": (
class: fg,
property: color,
values: theme-opacity-values(--fg)
),
混入
我们的 scss/mixins/ 目录包含驱动 Bootstrap 的代码片段,也可以在你自己的项目中使用。
代币
tokens() mixin 将 Sass map 输出为 CSS 自定义属性。每个组件都使用它来渲染其 token map:
@mixin tokens($map) {
@each $prop, $value in $map {
#{$prop}: #{$value};
}
}
.alert {
@include tokens($alert-tokens);
// Outputs: --alert-padding-x: ...; --alert-padding-y: ...; etc.
}
配色方案
提供prefers-color-scheme媒体查询的简写mixin,并支持light和dark配色方案。有关我们的配色模式mixin的信息,请参阅配色模式文档。
@mixin color-scheme($name) {
@media (prefers-color-scheme: #{$name}) {
@content;
}
}
.custom-element {
@include color-scheme(light) {
// Insert light mode styles here
}
@include color-scheme(dark) {
// Insert dark mode styles here
}
}
主题类
generate-theme-classes() mixin 循环遍历 $theme-colors 映射,并为每种颜色输出一个 .theme-* 类。每个类将通用 --theme-* 自定义属性映射到颜色的特定值,因此组件可以引用 --theme-base、--theme-bg 等,并从父 .theme-* 类中获取正确的调色板。它还会发出 .theme-reset,将这些令牌设置为 initial,以便嵌套组件再次使用它们自己的默认值:
@include generate-theme-classes();
// Outputs:
// .theme-primary { --theme-base: var(--primary-base); --theme-bg: var(--primary-bg); ... }
// .theme-success { --theme-base: var(--success-base); --theme-bg: var(--success-bg); ... }
// .theme-reset { --theme-base: initial; --theme-bg: initial; ... }
// ...
@mixin generate-theme-reset() {
.theme-reset {
$keys: ();
@each $color-map in map.values($theme-colors) {
@each $key in map.keys($color-map) {
$keys: map.merge($keys, ($key: true));
}
}
@each $key in map.keys($keys) {
--theme-#{$key}: initial;
}
}
}
口罩图标
mask-icon() 混入通过 CSS mask 渲染 SVG 图标,因此形状会用元素的 background-color 绘制。这使图标可以继承当前文本颜色,从而无需单独的 SVG 即可实现自动深色模式。我们在 关闭按钮、导航栏切换按钮、复选框标记、面包屑分隔符、日期选择器箭头 和 轮播控件 中使用此方法。
某些表单控件不能使用 mask,因为它们不支持伪元素,并且掩码会裁剪整个字段。<select> 三角图标和使用 .form-control-caret 的输入框是两个例子,它们改为保持单独的明暗 background-image SVG 作为非掩码背景图像。
@mixin mask-icon($icon: null, $size: contain, $position: center) {
@if $icon != null {
mask-image: $icon;
}
mask-repeat: no-repeat;
@if $position != null {
mask-position: $position;
}
@if $size != null {
mask-size: $size;
}
}
在元素上自行设置 background-color(混入仅输出 mask-* 属性),然后将你的图标作为遮罩图像传入。当图标根据条件应用时(例如按状态或方向),传入 null。
.custom-icon {
// Declare a custom CSS variable for the icon. This could be on the same
// element, `:root`, or a parent element. We're using a custom × icon. Be
// sure to wrap in `escape-svg()` as well.
--custom-icon: #{escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='black' stroke-linecap='round' stroke-width='2' d='m4 4 8 8m0-8-8 8'/></svg>"))};
width: 1rem;
height: 1rem;
background-color: currentcolor;
@include mask-icon($icon: var(--custom-icon));
}