Bootstrap 工具是通过我们的工具 API 生成的,可以通过 Sass 修改或扩展我们默认的工具类集合。我们的工具 API 基于一系列 Sass map和函数,用于生成具有各种选项的类族。如果你不熟悉 Sass map,请查阅 官方 Sass 文档 以入门。
$utilities 地图包含了我们所有的工具,并且如果存在的话,之后会与你的自定义 $utilities 地图合并。工具地图包含了一个带键的工具组列表,这些工具组接受以下选项:
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
property | 必填 | – | 属性的名称。可以是字符串,也可以是用空格分隔的字符串列表(例如,水平内边距或外边距),或者是一个 地图 属性到默认值的成对项(见 属性-值映射). |
values | 必填 | – | 值的列表,或者如果你不希望类名与值相同,可以使用映射。如果 null 用作地图键, class 不会被加在类名之前。 |
selector | 可选 | class | 生成的 CSS 规则集中 CSS 选择器的类型。可以是 class, attr-starts,或者 attr-includes. |
child-selector | 可选 | null | 一个子/后代选择器附加在工具类的选择器上,并被包裹在 :where() 用于零特异性。用于针对子元素而不是元素本身。 |
class | 可选 | null | 生成类的名称。如果未提供,并且 property 是一个字符串数组, class 将默认为第一个元素 property 数组。如果未提供,并且 property 是一个字符串,那个 values 钥匙用于 class 名字。 |
variables | 可选 | null | 在每个工具类中生成的 CSS 自定义属性的列表或映射。当为列表时,每个变量接收工具值。当为映射时,使用提供的静态值。 |
state | 可选 | null | 伪类变体列表(例如, :hover 或 :focus) 以生成前缀样式的类。 |
responsive | 可选 | false | 布尔值,指示是否应生成响应式类。 |
important | 可选 | false | 布尔值,表示是否 !important 应该添加到工具类的 CSS 规则中。 |
print | 可选 | false | 布尔值,指示是否需要生成打印类。 |
dark | 可选 | false | 布尔值,表示是否 dark: 应该生成带前缀的类,并限定于 @media (prefers-color-scheme: dark). |
enabled | 可选 | true | 设置为 false 在保留其定义的同时抑制工具类的输出 $utilities 地图 |
API 解释
所有实用变量都被添加到 $utilities 我们之中的变量 _utilities.scss 样式表,这是一个巨大的、嵌套的 Sass map。每组工具类都是从看起来像这样的代码块生成的:
$utilities: (
"opacity": (
property: opacity,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
输出如下:
.opacity-0 { opacity: 0; }
.opacity-25 { opacity: .25; }
.opacity-50 { opacity: .5; }
.opacity-75 { opacity: .75; }
.opacity-100 { opacity: 1; }
property
对于任何工具类,必须设置 property 键,并且它必须包含有效的 CSS 属性。该属性用于生成的工具类的规则集中。当省略 class 键时,它也充当默认的类名。考虑 text-decoration 工具类:
$utilities: (
"text-decoration": (
property: text-decoration,
values: none underline line-through
)
);
输出:
.text-decoration-none { text-decoration: none; }
.text-decoration-underline { text-decoration: underline; }
.text-decoration-line-through { text-decoration: line-through; }
属性值映射
property 键还接受 CSS 属性名称到默认值的 映射。这让单个工具类类可以一次设置多个属性,并且当值本身是映射时,可以覆盖单个属性。
当映射中某个属性的默认值为null时,该属性直接使用实用值。当设置了默认值时,除非工具类的值映射中包含匹配的键,否则将使用该默认值。
一个常见的模式是将 CSS 自定义属性(接收实用值)与引用它的常规属性配对:
$utilities: (
"bg-color": (
property: (
"--bg": null,
"background-color": var(--bg)
),
class: bg,
values: (
primary: var(--blue-500),
danger: var(--red-500),
)
)
);
输出:
.bg-primary { --bs-bg: var(--bs-blue-500); background-color: var(--bs-bg); }
.bg-danger { --bs-bg: var(--bs-red-500); background-color: var(--bs-bg); }
源 CSS 变量未使用 --bs- 前缀,该前缀会在我们使用 我们的 PostCSS 插件 编译的 CSS 中添加。
你还可以设置每个值的覆盖。当 values 包含一个嵌套的映射,其键与 property 映射中的属性匹配时,这些值将用于匹配的属性:
$utilities: (
"text-size": (
property: (
"font-size": 1rem,
"line-height": 1.5
),
class: text,
values: (
"sm": ("font-size": .875rem, "line-height": 1.25),
"lg": ("font-size": 1.25rem, "line-height": 1.75),
)
)
);
输出:
.text-sm { font-size: .875rem; line-height: 1.25; }
.text-lg { font-size: 1.25rem; line-height: 1.75; }
values
使用 values 键来指定生成的类名和规则中应使用哪些指定的 property 值。可以是列表或映射(在工具中或在 Sass 变量中设置)。
作为列表,就像使用 text-decoration 工具 一样:
values: none underline line-through
作为一个地图,就像使用 opacity 工具:
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
作为一个设置列表或映射的 Sass 变量,如我们在 position 工具 中所示:
values: $position-values
selector
| 选项 | 说明 |
|---|---|
| 无选择器 | 默认为 "class" |
"class" | 匹配具有指定值的类的元素 |
"attr-starts" | 匹配类名以某个字符串开头的元素 |
"attr-includes" | 匹配类名包含某个字符串的元素 |
使用 selector 选项可以更改生成的 CSS 规则集使用的 CSS 选择器。默认选项是生成类选择器。当使用属性选择器——attr-starts 或 attr-includes——需要 class 选项。我们在内部使用这些来简化其他工具的构建。
对于属性选择器,你最有可能希望使用 attr-includes 作为起始属性选择器,因为 CSS 中的属性选择器会应用于属性值中的整个类字符串。例如,[class^="name"] 将不会匹配 class="example name"。
例如,要从 .ratio-* 改为 [class*="ratio-"]:
$utilities: (
// Create an attribute selector utility
"aspect-ratio-attr": (
selector: "attr-includes",
class: "ratio-",
property: aspect-ratio,
values: var(--ratio),
),
// Create a CSS variable utility that matches the attribute selector utility
"aspect-ratio": (
property: --ratio,
class: ratio,
values: $aspect-ratios
),
);
请注意,--ratio 自定义属性将在编译后的 CSS 中通过 PostCSS 自动添加前缀 --bs-ratio。
输出如下:
[class*="ratio-"] { aspect-ratio: var(--bs-ratio); }
.ratio-auto { --bs-ratio: auto; }
.ratio-1x1 { --bs-ratio: 1 / 1; }
.ratio-4x3 { --bs-ratio: 4 / 3; }
.ratio-16x9 { --bs-ratio: 16 / 9; }
.ratio-21x9 { --bs-ratio: 21 / 9; }
child-selector
使用 child-selector 选项可以将 CSS 属性应用到具有该工具类的元素的子元素,而不是元素本身。生成的选择器被包裹在 :where() 中以实现零特异性,使其易于覆盖。这为我们内置的 space-x/y 和 divide-x/y 工具类提供了支持。
例如,我们的 space-x 工具使用 child-selector 在直接子元素之间添加水平间距:
$utilities: (
"space-x": (
property: margin-inline-end,
class: space-x,
child-selector: "> :not(:last-child)",
values: $spacers
)
);
输出包括:
:where(.space-x-1 > :not(:last-child)) { margin-inline-end: .25rem; }
:where(.space-x-2 > :not(:last-child)) { margin-inline-end: .375rem; }
:where(.space-x-3 > :not(:last-child)) { margin-inline-end: .5rem; }
/* ...through .space-x-12 */
child-selector 值可以是任何有效的 CSS 选择器。例如,你可以使用 :nth-child() 创建一个条纹行工具类:
$utilities: (
"striped-bg": (
property: background-color,
class: striped,
child-selector: "> :nth-child(odd)",
values: (
null: var(--bs-bg-1),
)
)
);
输出:
:where(.striped > :nth-child(odd)) { background-color: var(--bs-bg-1); }
或者使用 > * 定位所有直接子元素:
$utilities: (
"child-rounded": (
property: border-radius,
class: child-rounded,
child-selector: "> *",
values: (
null: var(--bs-border-radius),
0: 0,
)
)
);
输出:
:where(.child-rounded > *) { border-radius: var(--bs-border-radius); }
:where(.child-rounded-0 > *) { border-radius: 0; }
class
使用 class 选项更改已编译 CSS 中使用的类前缀。例如,要将.opacity-*更改为.o-*:
$utilities: (
"opacity": (
property: opacity,
class: o,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
输出:
.o-0 { opacity: 0; }
.o-25 { opacity: .25; }
.o-50 { opacity: .5; }
.o-75 { opacity: .75; }
.o-100 { opacity: 1; }
如果 class: null,为每个 values 键生成类:
$utilities: (
"visibility": (
property: visibility,
class: null,
values: (
visible: visible,
invisible: hidden,
)
)
);
输出:
.visible { visibility: visible; }
.invisible { visibility: hidden; }
变量
使用 variables 选项在每个工具类的规则集中生成 CSS 自定义属性。该值可以是 列表 或 映射。
当 variables 是一个 列表 时,每个变量都会接收到当前的效用值:
$utilities: (
"link-opacity": (
property: color,
class: link,
variables: link-color,
values: (
10: 10%,
50: 50%,
100: 100%,
)
),
);
输出:
.link-10 { --bs-link-color: 10%; color: 10%; }
.link-50 { --bs-link-color: 50%; color: 50%; }
.link-100 { --bs-link-color: 100%; color: 100%; }
当 variables 是一个 映射 时,提供的静态值将用于每个生成的类:
$utilities: (
"link-underline": (
property: text-decoration-color,
class: link-underline,
variables: (
"link-underline-opacity": 1
),
values: (...)
)
);
输出:
.link-underline-primary {
--bs-link-underline-opacity: 1;
text-decoration-color: ...;
}
州
使用 state 选项生成伪类变体。示例伪类有 :hover 和 :focus。当提供状态列表时,会为该伪类创建类名,前缀风格语法与响应式前缀模式匹配。例如,要在悬停时改变不透明度,添加 state: hover,你将在编译后的 CSS 中获得 .hover\:opacity:hover。
需要多个伪类吗?使用空格分隔的状态列表:state: hover focus。
$utilities: (
"opacity": (
property: opacity,
class: opacity,
state: hover,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
输出:
.hover\:opacity-0:hover { opacity: 0; }
.hover\:opacity-25:hover { opacity: .25; }
.hover\:opacity-50:hover { opacity: .5; }
.hover\:opacity-75:hover { opacity: .75; }
.hover\:opacity-100:hover { opacity: 1; }
响应式
添加 responsive 布尔值,用于生成响应式工具(例如, .md\:opacity-25) 穿过 所有断点.
$utilities: (
"opacity": (
property: opacity,
responsive: true,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
输出:
.opacity-0 { opacity: 0; }
.opacity-25 { opacity: .25; }
.opacity-50 { opacity: .5; }
.opacity-75 { opacity: .75; }
.opacity-100 { opacity: 1; }
@media (min-width: 576px) {
.sm\:opacity-0 { opacity: 0; }
.sm\:opacity-25 { opacity: .25; }
.sm\:opacity-50 { opacity: .5; }
.sm\:opacity-75 { opacity: .75; }
.sm\:opacity-100 { opacity: 1; }
}
@media (min-width: 768px) {
.md\:opacity-0 { opacity: 0; }
.md\:opacity-25 { opacity: .25; }
.md\:opacity-50 { opacity: .5; }
.md\:opacity-75 { opacity: .75; }
.md\:opacity-100 { opacity: 1; }
}
@media (min-width: 1024px) {
.lg\:opacity-0 { opacity: 0; }
.lg\:opacity-25 { opacity: .25; }
.lg\:opacity-50 { opacity: .5; }
.lg\:opacity-75 { opacity: .75; }
.lg\:opacity-100 { opacity: 1; }
}
@media (min-width: 1280px) {
.xl\:opacity-0 { opacity: 0; }
.xl\:opacity-25 { opacity: .25; }
.xl\:opacity-50 { opacity: .5; }
.xl\:opacity-75 { opacity: .75; }
.xl\:opacity-100 { opacity: 1; }
}
@media (min-width: 1536px) {
.\32 xl\:opacity-0 { opacity: 0; }
.\32 xl\:opacity-25 { opacity: .25; }
.\32 xl\:opacity-50 { opacity: .5; }
.\32 xl\:opacity-75 { opacity: .75; }
.\32 xl\:opacity-100 { opacity: 1; }
}
打印
启用 print 选项将 也 为打印生成工具类,这些类仅在 @media print { ... } 媒体查询内应用。
$utilities: (
"opacity": (
property: opacity,
print: true,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
输出:
.opacity-0 { opacity: 0; }
.opacity-25 { opacity: .25; }
.opacity-50 { opacity: .5; }
.opacity-75 { opacity: .75; }
.opacity-100 { opacity: 1; }
@media print {
.print\:opacity-0 { opacity: 0; }
.print\:opacity-25 { opacity: .25; }
.print\:opacity-50 { opacity: .5; }
.print\:opacity-75 { opacity: .75; }
.print\:opacity-100 { opacity: 1; }
}
黑暗
启用 dark 选项生成 dark: 带前缀的类作用域于 @media (prefers-color-scheme: dark)这遵循与响应式和打印工具相同的前缀惯例。
$utilities: (
"bg-color": (
property: background-color,
class: bg,
dark: true,
values: (
white: #fff,
black: #000,
)
)
);
输出:
.bg-white { background-color: #fff; }
.bg-black { background-color: #000; }
@media (prefers-color-scheme: dark) {
.dark\:bg-white { background-color: #fff; }
.dark\:bg-black { background-color: #000; }
}
已启用
将 enabled: false 设置为抑制工具类的输出,而不将其从 $utilities 映射中移除。当你希望保留工具类的定义以供参考或下游 map.get() 调用,但又不希望它生成任何 CSS 时,这非常有用。有关此示例所需的加载顺序,请参见 使用 API。
// _my-utilities.scss
@use "sass:map";
@use "bootstrap/scss/config" as *;
@use "bootstrap/scss/utilities";
$utilities: map.merge(
$utilities,
(
"float": map.merge(
map.get($utilities, "float"),
(enabled: false),
),
)
);
重要性
由 API 生成的工具类不再包括 !important 在 v6 中默认如此。这是因为我们现在使用 CSS 层来确保工具类按预期覆盖组件和修饰符类。你可以启用 !important 通过设置按每个效用的基础 important 选项到 true.
$utilities: (
"opacity": (
property: opacity,
important: true,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
这将生成带有 !important 的工具类:
.opacity-0 { opacity: 0 !important; }
.opacity-25 { opacity: .25 !important; }
.opacity-50 { opacity: .5 !important; }
.opacity-75 { opacity: .75 !important; }
.opacity-100 { opacity: 1 !important; }
使用 API
现在你已经熟悉了工具类 API 的工作原理,学习如何添加你自己的自定义类并修改我们的默认工具类。
下面的示例使用了两种模式。请选择与你的更改匹配的模式。
- 一个文件—配置
$utilities当你加载时bootstrap/scss/bootstrap使用此模式来添加工具类、替换工具类或删除工具类。 - 两个文件—放一个
map.merge()调用一个部分。然后在之前加载该部分bootstrap/scss/bootstrap当你的更改必须读取默认定义时,请使用此模式。示例包括新值、新类前缀,或你保留的组上的新响应式变体。
单文件模式需要一个 @use 规则:
// my-bootstrap.scss
@use "bootstrap/scss/bootstrap" with (
$utilities: (
// Your utility groups go here
)
);
Bootstrap 将你的映射与 map.merge() 合并。此合并是浅层的。你的工具组会用相同的键替换整个默认组。在每个生成 CSS 的组中提供 property 和 values 键。
Sass 不能在同一个文件中读取一个模块并配置同一个模块。因此,某些更改需要使用两个文件的模式。bootstrap/scss/config 模块声明了 $utilities。bootstrap/scss/utilities 模块用默认定义填充它。你的部分文件加载了这两个模块。然后它将新的映射写回到配置模块。
部分加载配置模块时使用 as *。这避免了使用命名空间前缀,因此可以直接引用 $utilities。对 $utilities 的赋值随后会写回配置模块。
对于仅实用功能的构建,先加载 bootstrap/scss/utilities 然后加载 bootstrap/scss/utilities/api。API 模块只输出工具类,不输出其他内容。
// my-bootstrap-utilities.scss
@use "bootstrap/scss/utilities" with (
$utilities: (
// Your utility groups go here
)
);
@use "bootstrap/scss/utilities/api";
覆盖工具类
使用相同的键覆盖现有的工具类。在加载 Bootstrap 时,将新定义传递到 $utilities 配置中。例如,使用我们现有的 overflow 工具类类定义:
"overflow": (
property: overflow,
values: auto hidden visible scroll,
),
"overflow-x": (
property: overflow-x,
values: auto hidden visible scroll,
),
"overflow-y": (
property: overflow-y,
values: auto hidden visible scroll,
),
如果你想让它们具备响应性,并调整所使用的数值,你可以这样做:
// my-bootstrap.scss
@use "bootstrap/scss/bootstrap" with (
$utilities: (
"overflow": (
property: overflow,
responsive: true,
values: visible hidden scroll auto,
),
)
);
你的组会替换默认组。保持 property 键,否则构建会因错误而停止。
添加工具类
使用$utilities配置添加一个新工具类。Bootstrap会将你的映射合并到它的默认值上,因此只需提供新的工具类。
// my-bootstrap.scss
@use "bootstrap/scss/bootstrap" with (
$utilities: (
"cursor": (
property: cursor,
class: cursor,
responsive: true,
values: auto pointer grab,
),
)
);
修改工具类
使用map.get()和map.merge()修改现有工具。此更改会读取默认定义,因此需要两个文件模式。在下面的示例中,我们正在向width工具添加额外的值:
// _my-utilities.scss
@use "sass:map";
@use "bootstrap/scss/config" as *;
// Fills `$utilities` with the default definitions
@use "bootstrap/scss/utilities";
$utilities: map.merge(
$utilities,
(
"width": map.merge(
map.get($utilities, "width"),
(
values: map.merge(
map.get(map.get($utilities, "width"), "values"),
(20: 20%),
),
),
),
)
);
先加载你的局部内容。然后加载 Bootstrap:
// my-bootstrap.scss
@use "my-utilities";
@use "bootstrap/scss/bootstrap";
启用响应式
你可以为当前默认情况下不响应的现有工具集启用响应类。此更改会保留默认定义,因此需要使用双文件模式。例如,要使 border 类具有响应性:
// _my-utilities.scss
@use "sass:map";
@use "bootstrap/scss/config" as *;
@use "bootstrap/scss/utilities";
$utilities: map.merge(
$utilities,
(
"border": map.merge(
map.get($utilities, "border"),
(responsive: true),
),
)
);
如上所示,在bootstrap/scss/bootstrap之前加载此部分。你也可以使用单文件模式重新声明整个组。参见 覆盖工具。
这将为每个断点生成 .border 和 .border-0 的响应式变体。你生成的 CSS 将如下所示:
.border { ... }
.border-0 { ... }
@media (min-width: 576px) {
.sm\:border { ... }
.sm\:border-0 { ... }
}
@media (min-width: 768px) {
.md\:border { ... }
.md\:border-0 { ... }
}
@media (min-width: 1024px) {
.lg\:border { ... }
.lg\:border-0 { ... }
}
@media (min-width: 1280px) {
.xl\:border { ... }
.xl\:border-0 { ... }
}
@media (min-width: 1536px) {
.2xl\:border { ... }
.2xl\:border-0 { ... }
}
重命名工具
缺少 v4 工具,还是习惯了另一种命名约定?工具 API 可用于覆盖给定工具的结果 class。此更改保留默认定义,因此需要双文件模式。例如,将 .ms-* 工具重命名为旧式 .ml-*:
// _my-utilities.scss
@use "sass:map";
@use "bootstrap/scss/config" as *;
@use "bootstrap/scss/utilities";
$utilities: map.merge(
$utilities,
(
"margin-start": map.merge(
map.get($utilities, "margin-start"),
(class: ml),
),
)
);
在 bootstrap/scss/bootstrap 之前加载此部分,如上所示。
移除工具类
使用 $utilities 配置移除默认工具。将组键设置为 null。
// my-bootstrap.scss
@use "bootstrap/scss/bootstrap" with (
$utilities: (
"width": null,
"float": null,
)
);
你也可以使用 map.remove() Sass 函数 移除工具。这函数会读取默认映射,所以需要两个文件的模式。
// _my-utilities.scss
@use "sass:map";
@use "bootstrap/scss/config" as *;
@use "bootstrap/scss/utilities";
$utilities: map.remove($utilities, "width", "float");
在 bootstrap/scss/bootstrap 之前加载此部分,如上所示。
添加、移除、修改
你可以使用 map.merge() Sass 函数 一次性添加、删除和修改许多工具类。以下是如何将前面的示例合并为一个更大的 map 的方法。
// _my-utilities.scss
@use "sass:map";
@use "bootstrap/scss/config" as *;
@use "bootstrap/scss/utilities";
$utilities: map.merge(
$utilities,
(
// Remove the `width` utility
"width": null,
// Make an existing utility responsive
"border": map.merge(
map.get($utilities, "border"),
(responsive: true),
),
// Add a new utility
"cursor": (
property: cursor,
class: cursor,
responsive: true,
values: auto pointer grab,
),
)
);
然后在 Bootstrap 之前加载部分内容:
// my-bootstrap.scss
@use "my-utilities";
@use "bootstrap/scss/bootstrap";