bootstrap-utility-api
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBootstrap 6 utility API
Bootstrap 6 utility API
Every utility class Bootstrap ships is generated from one Sass map, . Each entry describes a family of classes — the property it sets, the values it accepts, and which variants to generate. Customizing utilities means editing that map, not writing CSS.
$utilitiesBootstrap 自带的所有工具类都由一个 Sass 映射 生成。每个条目描述了一类类族——其设置的属性、接受的值,以及要生成的变体。自定义工具类意味着编辑这个映射,而非编写 CSS。
$utilitiesWorkflow
工作流程
- Step 1: Understand how generation works
- Step 2: Read a utility definition
- Step 3: Add a utility
- Step 4: Modify, rename, or remove a default utility
- Step 5: Generate responsive, state, print, and dark variants
- Step 6: Compose values with custom properties and advanced selectors
- Step 7: Trim the generated CSS
- Step 8: Add a utility to Bootstrap itself
- Step 9: Verify
- 步骤 1:理解生成原理
- 步骤 2:解读工具类定义
- 步骤 3:添加工具类
- 步骤 4:修改、重命名或移除默认工具类
- 步骤 5:生成响应式、状态、打印和深色模式变体
- 步骤 6:使用自定义属性和高级选择器组合值
- 步骤 7:精简生成的 CSS
- 步骤 8:向 Bootstrap 本身添加工具类
- 步骤 9:验证
Step 1: Understand how generation works
步骤 1:理解生成原理
scss/utilities/_api.scssscss
@include generate-utility-at-properties($utilities);
@layer utilities {
@include generate-utilities-loop($utilities, $breakpoints);
}Three consequences worth knowing before you touch anything:
- Utilities are the last cascade layer, so they win over component styles without needing . Only groups that opt in with
!importantadd it.important: true - registration happens outside the layer. Every custom property a utility assigns (
@property,--bg,--fg,--bc, …) is registered with--rounded-size, so applyingsyntax: "*"; inherits: falsedoesn't leak its composed value into descendants. New utilities that assign custom properties get this automatically..border-inverse - The map is configured on the module, not
config.bootstrapis declared in$utilitiesand only populated inscss/_config.scss(which loads config withscss/_utilities.scss). Configuring the wrong module fails:@use "config" as *
scss
// Does NOT work — "This variable was not declared with !default in the @used module."
@use "bootstrap/scss/bootstrap" with (
$utilities: (…)
);
// Works — configure config first, then load Bootstrap
@use "bootstrap/scss/config" with (
$utilities: (…)
);
@use "bootstrap/scss/bootstrap";The same applies to any variable that lives in (, , , ). Variables declared in a partial that forwards — , , — can be configured on directly.
_config.scss$radius$spacers$breakpoints$zindex-levelsbootstrap.scss$root-tokens$colors$bluebootstrapscss/utilities/_api.scssscss
@include generate-utility-at-properties($utilities);
@layer utilities {
@include generate-utilities-loop($utilities, $breakpoints);
}在进行任何修改之前,有三个要点值得了解:
- 工具类位于最后一个级联层,因此无需 就能覆盖组件样式。只有通过
!important显式开启的组才会添加important: true。!important - 注册在层之外进行。 工具类分配的每个自定义属性(
@property、--bg、--fg、--bc等)都会以--rounded-size的规则注册,因此使用syntax: "*"; inherits: false不会将其组合值泄漏到后代元素中。分配自定义属性的新工具类会自动获得此特性。.border-inverse - 映射是在 模块中配置的,而非
config模块。bootstrap在$utilities中声明,仅在scss/_config.scss中被填充(该文件通过scss/_utilities.scss加载配置)。配置错误的模块会导致失败:@use "config" as *
scss
// Does NOT work — "This variable was not declared with !default in the @used module."
@use "bootstrap/scss/bootstrap" with (
$utilities: (…)
);
// Works — configure config first, then load Bootstrap
@use "bootstrap/scss/config" with (
$utilities: (…)
);
@use "bootstrap/scss/bootstrap";这同样适用于 中的所有变量(、、、)。而在 转发的分部文件中声明的变量(如 、、)可以直接在 模块上配置。
_config.scss$radius$spacers$breakpoints$zindex-levelsbootstrap.scss$root-tokens$colors$bluebootstrapStep 2: Read a utility definition
步骤 2:解读工具类定义
A group is a map. The simplest form needs two keys:
scss
"overflow": (
property: overflow,
values: auto hidden visible scroll,
),The full option set, as validated by :
generate-utility()| Key | Required | What it does |
|---|---|---|
| Yes | Property name, space-separated list of names, or a map of property-to-value pairs |
| Yes | List (class suffix equals the value) or map (keys become suffixes; a |
| No | Class name to use instead of the property name |
| No | |
| No | Descendant selector, wrapped in |
| No | Custom properties to emit — a map of static values, or a list that each receive the utility value |
| No | Pseudo-class variants to generate, e.g. |
| No | Generate a class per breakpoint (default |
| No | Generate |
| No | Generate |
| No | Append |
| No | Set |
The generator validates as it goes, which makes mistakes cheap to find: a missing or is a hard , a non-boolean is a hard , and a misspelled key is a listing the valid ones.
propertyvalues@errorresponsive@error@warn一个工具类组就是一个映射。最简单的形式需要两个键:
scss
"overflow": (
property: overflow,
values: auto hidden visible scroll,
),完整的选项集(由 验证)如下:
generate-utility()| 键 | 是否必填 | 作用 |
|---|---|---|
| 是 | 属性名称、以空格分隔的名称列表,或属性-值对的映射 |
| 是 | 列表(类后缀等于值)或映射(键作为后缀; |
| 否 | 替代属性名称使用的类名 |
| 否 | 可选值为 |
| 否 | 后代选择器,包裹在 |
| 否 | 要输出的自定义属性——可以是静态值的映射,或每个都接收工具类值的列表 |
| 否 | 要生成的伪类变体,例如 |
| 否 | 为每个断点生成一个类(默认 |
| 否 | 生成带 |
| 否 | 在 |
| 否 | 追加 |
| 否 | 设置为 |
生成器会在运行过程中进行验证,因此错误很容易发现:缺少 或 会触发强制 , 不是布尔值也会触发强制 ,而拼写错误的键会触发 并列出所有有效键。
propertyvalues@errorresponsive@error@warnStep 3: Add a utility
步骤 3:添加工具类
Your map is merged over Bootstrap's defaults, so pass only what's new:
scss
@use "bootstrap/scss/config" with (
$utilities: (
"cursor": (
property: cursor,
class: cursor,
responsive: true,
values: auto pointer grab,
),
)
);
@use "bootstrap/scss/bootstrap";That yields , , , plus through .
.cursor-auto.cursor-pointer.cursor-grab.sm:cursor-*.2xl:cursor-*Value shapes control the class names:
scss
// List — suffix is the value itself: .cursor-pointer
values: auto pointer grab,
// Map — keys become suffixes: .tint-brand
values: (brand: var(--purple-500), muted: var(--gray-200)),
// null key — no suffix at all: .shout
values: (null: uppercase),你的映射会与 Bootstrap 的默认映射合并,因此只需传入新增的内容:
scss
@use "bootstrap/scss/config" with (
$utilities: (
"cursor": (
property: cursor,
class: cursor,
responsive: true,
values: auto pointer grab,
),
)
);
@use "bootstrap/scss/bootstrap";这会生成 、、,以及从 到 的响应式类。
.cursor-auto.cursor-pointer.cursor-grab.sm:cursor-*.2xl:cursor-*值的形式决定了类名:
scss
// List — suffix is the value itself: .cursor-pointer
values: auto pointer grab,
// Map — keys become suffixes: .tint-brand
values: (brand: var(--purple-500), muted: var(--gray-200)),
// null key — no suffix at all: .shout
values: (null: uppercase),Step 4: Modify, rename, or remove a default utility
步骤 4:修改、重命名或移除默认工具类
The merge is shallow: supplying an existing group key replaces that entire group. Overriding one option and omitting the rest fails loudly —
scss
// Errors: "Utility is missing required `property` key"
"overflow": (
responsive: true,
values: visible hidden scroll auto,
),so copy the full definition from and add your change:
scss/_utilities.scssscss
@use "bootstrap/scss/config" with (
$utilities: (
// Make overflow responsive
"overflow": (
property: overflow,
values: auto hidden visible scroll,
responsive: true,
),
// Remove a family entirely
"width": null,
// Rename .ms-* to v4-style .ml-*: drop the original, add a replacement
"margin-start": null,
"margin-start-alias": (
property: margin-inline-start,
class: ml,
responsive: true,
values: (0: 0, 1: var(--spacer-1), 2: var(--spacer-2), auto: auto),
),
)
);
@use "bootstrap/scss/bootstrap";Note the CSS tokens in that last group. The file configuring can't read Bootstrap's Sass members — , , and helpers like aren't in scope yet — so restate values as CSS tokens (, which tracks the spacer scale) or as literals.
config$spacers$negative-spacersmap-merge-multiple()var(--spacer-2)To extend an existing family without copying its definition, register a new group that reuses the same :
classscss
"width-extra": (
property: width,
class: w,
responsive: true,
values: (10: 10%, 15: 15%),
),This adds and next to Bootstrap's … , and is usually the better choice — it survives Bootstrap updates that change the original group.
.w-10.w-15.w-25.w-100Prefer over when you want the definition to stay visible in the map (useful in a shared config where the group is documented but intentionally off).
enabled: falsenull合并是浅合并:提供一个已有的组键会替换整个组。仅覆盖一个选项而省略其余选项会直接报错——
scss
// Errors: "Utility is missing required `property` key"
"overflow": (
responsive: true,
values: visible hidden scroll auto,
),因此请从 中复制完整定义,然后添加你的修改:
scss/_utilities.scssscss
@use "bootstrap/scss/config" with (
$utilities: (
// Make overflow responsive
"overflow": (
property: overflow,
values: auto hidden visible scroll,
responsive: true,
),
// Remove a family entirely
"width": null,
// Rename .ms-* to v4-style .ml-*: drop the original, add a replacement
"margin-start": null,
"margin-start-alias": (
property: margin-inline-start,
class: ml,
responsive: true,
values: (0: 0, 1: var(--spacer-1), 2: var(--spacer-2), auto: auto),
),
)
);
@use "bootstrap/scss/bootstrap";注意最后一组中的 CSS 令牌。配置 的文件无法读取 Bootstrap 的 Sass 成员——、 以及 等辅助函数此时还不在作用域内——因此请将值重新表述为 CSS 令牌(如 ,它会跟随间距尺度变化)或字面量。
config$spacers$negative-spacersmap-merge-multiple()var(--spacer-2)要扩展现有类族而无需复制其定义,可以注册一个复用相同 的新组:
classscss
"width-extra": (
property: width,
class: w,
responsive: true,
values: (10: 10%, 15: 15%),
),这会在 Bootstrap 原有的 到 之外新增 和 ,通常这是更好的选择——即使 Bootstrap 更新修改了原始组,这些扩展也能正常工作。
.w-25.w-100.w-10.w-15如果你希望定义在映射中保持可见(在共享配置中很有用,即该组有文档说明但被有意关闭),请优先使用 而非 。
enabled: falsenullStep 5: Generate responsive, state, print, and dark variants
步骤 5:生成响应式、状态、打印和深色模式变体
v6 uses prefixes, not infixes or suffixes. All four variant types compose with the base class name:
| Option | Generated class | Notes |
|---|---|---|
| | One pass per key in |
| | Selector is |
| | Wrapped in |
| | Wrapped in |
responsivestate.md:hover:cursor-pointerv6 版本使用前缀而非中缀或后缀。所有四种变体类型都与基类名组合:
| 选项 | 生成的类 | 说明 |
|---|---|---|
| | 为 |
| | 选择器为 |
| | 包裹在 |
| | 包裹在 |
responsivestate.md:hover:cursor-pointerStep 6: Compose values with custom properties and advanced selectors
步骤 6:使用自定义属性和高级选择器组合值
Most color-ish utilities don't set the property directly. They assign a local custom property and then consume it, which is what makes opacity and composition work:
scss
"tint": (
property: (
"--tint": null,
"background-color": var(--tint),
),
class: tint,
values: (brand: var(--purple-500)),
),A value in the property map means "receive the utility's value"; every other entry is emitted as written. The above generates:
nullcss
.tint-brand {
--tint: var(--purple-500);
background-color: var(--tint);
}Related mechanics:
- emits extra custom properties. As a map, each gets a static value on every class in the group; as a list, each receives the utility's value.
variables - Property maps plus map values. When is a map and a
propertyentry is itself a map keyed by property name, each property picks its own value — useful for a group that sets several related properties at different values.values - /
selector: attr-startstargetsattr-includes/[class^="…"]instead of a class, and requires a[class*="…"]key. Bootstrap uses it soclasscan feed.ratio-16x9throughaspect-ratio.--ratio - wraps the rule in
child-selector, e.g.:where(). Zero specificity means a child's own styles still win.:where(.stack-gap-1 > *)
Custom property names are written unprefixed in Sass. Bootstrap's dist and CDN CSS run PostCSS to add , so compiling the source yourself keeps them unprefixed.
--bs-大多数颜色类工具类不会直接设置属性。它们会分配一个本地自定义属性然后再使用它,这就是透明度和组合效果得以实现的原因:
scss
"tint": (
property: (
"--tint": null,
"background-color": var(--tint),
),
class: tint,
values: (brand: var(--purple-500)),
),属性映射中的 值表示「接收工具类的值」;其他所有条目都会按原样输出。上述代码会生成:
nullcss
.tint-brand {
--tint: var(--purple-500);
background-color: var(--tint);
}相关机制:
- 会输出额外的自定义属性。作为映射时,每个属性都会在组内的每个类上获得一个静态值;作为列表时,每个属性都会接收工具类的值。
variables - 属性映射加映射值。 当 是一个映射,且某个
property条目本身是一个以属性名为键的映射时,每个属性会选择自己的值——适用于需要为多个相关属性设置不同值的工具类组。values - /
selector: attr-starts会以attr-includes/[class^="…"]而非类作为目标,且需要提供[class*="…"]键。Bootstrap 使用此特性让class能够通过.ratio-16x9为--ratio提供值。aspect-ratio - 会将规则包裹在
child-selector中,例如:where()。零特异性意味着子元素自身的样式仍然优先。:where(.stack-gap-1 > *)
自定义属性名称在 Sass 中编写时不带前缀。Bootstrap 的发行版和 CDN CSS 会通过 PostCSS 添加 前缀,因此如果你自行编译源码,这些属性将保持无前缀状态。
--bs-Step 7: Trim the generated CSS
步骤 7:精简生成的 CSS
Utilities are the biggest slice of Bootstrap's CSS, and the map is the cheapest place to cut:
-
Start from the utilities-only entry point if you don't need components:scss
@use "bootstrap/scss/config" with ($utilities: (…)); @use "bootstrap/scss/bootstrap-utilities"; -
Set unused groups to(or
null) rather than relying on the minifier or a purge step.enabled: false -
Turnoff on groups you only use at one breakpoint — a responsive group costs six copies of itself.
responsive -
Narrowmaps instead of deleting whole groups when you only need a few steps.
values
See Optimize for the wider picture, including Lightning CSS and purging.
工具类是 Bootstrap CSS 中占比最大的部分,而修改映射是最简便的精简方式:
-
如果你不需要组件,请从仅含工具类的入口点开始:scss
@use "bootstrap/scss/config" with ($utilities: (…)); @use "bootstrap/scss/bootstrap-utilities"; -
将未使用的组设置为(或
null),而非依赖压缩工具或清除步骤。enabled: false -
对于仅在一个断点使用的组,请关闭——一个响应式组会生成六份自身的副本。
responsive -
如果你只需要少数几个档位,请缩小映射的范围,而非删除整个组。
values
更全面的信息请参阅优化,包括 Lightning CSS 和样式清除。
Step 8: Add a utility to Bootstrap itself
步骤 8:向 Bootstrap 本身添加工具类
When contributing a utility to the framework rather than a project:
- Add the group to the map in
$utilities, near related groups, wrapped inscss/_utilities.scss/// scss-docs-start utils-<name>markers.// scss-docs-end utils-<name> - Prefer composing through a custom property when the utility should interact with opacity or theme colors, and reuse existing token values (,
$spacers,$util-opacity) instead of literals.theme-color-refs() - Document it on the matching page in , rendering the definition with
site/src/content/docs/utilities/, and add a<ScssDocs name="utils-<name>" file="scss/_utilities.scss" />entry if the page is new.site/data/sidebar.yml - Add coverage in , which calls the generator mixins directly with a fixture map.
scss/tests/utilities/_api.test.scss - Run . Its
npm run cssstep regeneratescss-docs, which the docs read — commit it alongside your change.dist/css/bootstrap-utilities.metadata.json
如果你是要为框架贡献工具类,而非在项目中使用:
- 将该组添加到 的
scss/_utilities.scss映射中,放在相关组附近,并用$utilities/// scss-docs-start utils-<name>标记包裹。// scss-docs-end utils-<name> - 如果工具类需要与透明度或主题色交互,请优先通过自定义属性进行组合,并复用现有的令牌值(、
$spacers、$util-opacity)而非字面量。theme-color-refs() - 在 下的对应页面中编写文档,使用
site/src/content/docs/utilities/渲染定义,如果是新页面,请在<ScssDocs name="utils-<name>" file="scss/_utilities.scss" />中添加条目。site/data/sidebar.yml - 在 中添加测试覆盖,该文件会使用测试映射直接调用生成器 mixin。
scss/tests/utilities/_api.test.scss - 运行 。其中的
npm run css步骤会重新生成css-docs(供文档读取)——请将其与你的修改一并提交。dist/css/bootstrap-utilities.metadata.json
Step 9: Verify
步骤 9:验证
- , then
npm run css-lint.npm run css - Grep the compiled CSS for the classes you expected, including the escaped variants (), and confirm nothing you removed is still present.
\.md\\:cursor-pointer - Confirm new custom properties appear in the block at the top of the file — if one is missing, the utility isn't assigning it through
@propertyorproperty.variables - Watch the Sass output for lines about unknown keys; they're the fastest signal that an option was misspelled and silently ignored.
@warn - Check specificity in the browser: utilities should override component styles through the layer order alone, without .
!important
- 运行 ,然后运行
npm run css-lint。npm run css - 在编译后的 CSS 中搜索你预期的类,包括转义后的变体(),并确认已移除的内容不再存在。
\.md\\:cursor-pointer - 确认新的自定义属性出现在文件顶部的 块中——如果缺少某个属性,说明该工具类没有通过
@property或property分配它。variables - 留意 Sass 输出中关于未知键的 行;这是发现选项拼写错误并被静默忽略的最快方式。
@warn - 在浏览器中检查特异性:工具类应该仅通过层顺序就能覆盖组件样式,无需 。
!important