它是如何工作的
CSS 在 Bootstrap 中掌控每一个组件的过渡。JavaScript 仅切换一个状态类,然后等待过渡完成,再触发事件或移除元素。
这意味着你可以仅用 CSS 来重新设计动画效果。你无需重新实现组件就能改变它的动画方式。
每个动画组件都遵循相同的三条规则:
- 基本选择器包含隐藏状态,以及
transition声明。 - 状态类包含可见状态。
@starting-style提供进入时的状态,因为在状态类生效之前元素尚未渲染。
消息提示是参考实现。
// Animated variant (default). `display` transitions discretely so the toast
// stays laid out until the fade-out finishes. Add .toast-instant to skip it.
&:not(.toast-instant) {
opacity: 0;
@include transition-props(
var(--toast-transition-property),
var(--toast-transition-duration),
var(--toast-transition-timing),
allow-discrete
);
}
&.show {
display: flex;
opacity: 1;
}
display 与 allow-discrete 进行过渡,因此 toast 会保持显示状态直到淡出结束。没有它,该元素会在第一帧就消失,你将看不到退出动画。
状态类
JavaScript 添加和移除一小组固定的类。对这些类进行样式设置,你的自定义将随组件一起生效。
| 类名 | 含义 |
|---|---|
.show | 该组件已显示。它的缺失表示隐藏状态。用于折叠、菜单、气泡提示、轻提示和工具提示。折叠不会切换其他内容。 |
.active | 标签页显示的状态,同时它还标记所选的标签页。 |
.hiding | 仅在退出过渡播放时显示。过渡结束后,Bootstrap 会将其移除。用于警报、对话框和抽屉。 |
.{component}-instant | 从其过渡中选择一个元素,例如 .toast-instant 或者 .dialog-instant. |
.{component}-static | 一个简短的反弹,表示模态拒绝关闭,例如 .dialog-static. |
.hiding 适用于必须在自身退出后仍然存活的组件。警告从 DOM 中被移除,对话框离开顶层,所以两者都需要一个标记退出状态的类。仅仅隐藏的组件可以改用 .show。
自定义动作
代币三重奏
每个动画组件都暴露相同的三个自定义属性。
| 自定义属性 | 用途 |
|---|---|
--bs-{component}-transition-property | 要进行动画的属性。 |
--bs-{component}-transition-duration | 动画运行的时长。设置为0s可以移除动画。 |
--bs-{component}-transition-timing | 缓动曲线。 |
因为属性列表是一个令牌,你可以在不重写整个声明的情况下对新内容进行动画。将transform添加到 toast 列表中,toast 会在淡出时滑动。按下按钮可以重放它。
.toast-slide {
--bs-toast-transition-property: opacity, transform, display;
--bs-toast-transition-duration: .3s;
--bs-toast-transition-timing: ease-out;
transform: translateY(1rem);
}
.toast-slide.show {
transform: none;
}
在列表中保留 discrete 属性。toast 和菜单需要 display,对话框和抽屉需要 visibility。该属性可以让元素在退出动画结束之前保持渲染状态。
尺寸动画
折叠和折叠面板动画改变的是大小,而不是不透明度,所以它们添加了 interpolate-size 以让 0 插值到打开状态的 auto。没有 JavaScript 测量内容。没有 interpolate-size 的浏览器会一次性打开和关闭元素,这就是为什么折叠动画始终剪裁动画轴的原因。
崩塌三元组将组件名称放在最后,因为这两个组件共享它。
// stylelint-disable custom-property-no-missing-var-function
$collapse-tokens: defaults(
(
--transition-collapse-property: "block-size, display",
--transition-collapse-duration: .35s,
--transition-collapse-timing: ease,
),
$collapse-tokens
);
// stylelint-enable custom-property-no-missing-var-function
共享缓动
对话框、抽屉和菜单从 :root 读取一个缓动曲线,因此单个重写会重新设置所有三个覆盖层的样式。
// Shared easing curve for overlay components (dialog, drawer, menu)
--transition-timing-overlay: cubic-bezier(.22, 1, .36, 1),
移除动议
你有四个选项,从最窄到最宽:
- 将组件的
-instant类添加到一个元素,例如.toast-instant。 - 将
.transition-none工具类 添加到一个元素。 - 为组件或子树将
-duration令牌设置为0s。 - 将
$enable-transitionsSass 选项设置为false以在构建时移除所有过渡效果。
Bootstrap 将其过渡封装在 prefers-reduced-motion: no-preference 中,因此要求减少动画的用户已经可以立即看到状态变化。更多信息请参见 减少动画。
JavaScript 会在等待之前读取计算出的过渡持续时间。当持续时间为 0s 时,事件和承诺会立即解决,无论是什么移除了动画。
事件与承诺
show() 和 hide() 返回在过渡结束后解决的承诺。相应的 shown 和 hidden 事件同时触发。
const toast = new bootstrap.Toast('#myToast')
await toast.show()
// The fade-in has finished.
一个没有过渡的元素仍然会被解析,只是在下一次时钟周期。