因为Bootstrap 5.3+的暗黑模式依赖data-bs-theme属性驱动:root级CSS变量,而body类名不触发变量重算;必须操作document.documentElement并配合[data-bs-theme="dark"]规则和update()调用。

为什么直接改 body 类名不触发 Bootstrap 5 暗黑主题?
Bootstrap 5 官方不内置暗黑主题,也**不监听 body 的 dark 类变化来重绘颜色变量**。你手动加 class="dark" 或用 JS 切换,background-color、color 等样式不会自动响应——因为 Bootstrap 的 CSS 是静态编译出来的,没绑定 CSS 变量监听逻辑。
真正起效的方式是:用 CSS 自定义属性(--bs-* 变量)覆盖默认值,并让这些变量随主题切换实时更新。
如何在 Bootstrap 5 中注入可切换的 CSS 变量?
Bootstrap 5.3+ 开始在源码中大量使用 --bs-* 变量(如 --bs-body-color、--bs-primary),但它们默认只在 :root 中声明一次。要支持切换,得让同一组变量在不同上下文(比如 data-bs-theme="dark")下有不同取值。
- 在
中定义两套:root和[data-bs-theme="dark"]规则,后者覆盖前者 - Bootstrap 的组件样式必须基于这些变量(例如
color: var(--bs-body-color)),而它确实这么做了——所以只要变量值变了,按钮、卡片、文字都会跟着变 - 不要试图修改 Bootstrap 的 SCSS 源码再重新编译;直接用 CSS 变量覆盖更轻量、可运行时切换
示例最小覆盖:
立即学习“前端免费学习笔记(深入)”;
:root {
--bs-body-color: #212529;
--bs-body-bg: #fff;
--bs-primary: #0d6efd;
}
[data-bs-theme="dark"] {
--bs-body-color: #f8f9fa;
--bs-body-bg: #212529;
--bs-primary: #6ea8fe;
}
切换主题时,该用 dataset 还是 class?
必须用 data-bs-theme 属性,而不是 class。原因很实际:
- Bootstrap 5.3+ 的官方暗黑文档示例明确使用
data-bs-theme="dark"作为开关(见其 Color modes 页面) - 它的所有内置组件(如
.btn、.card)的暗色样式规则都写在[data-bs-theme="dark"] .btn这类选择器下,不是.dark .btn - 用 JS 切换:
document.documentElement.dataset.bsTheme = 'dark'或document.documentElement.setAttribute('data-bs-theme', 'dark') - 别漏掉
localStorage持久化,否则刷新就回白天
哪些变量必须手动补全?Bootstrap 5 没覆盖全
Bootstrap 只定义了核心颜色变量(--bs-primary、--bs-body-bg 等),但像表单控件的 focus ring、悬停阴影、禁用态文本等,它仍用硬编码颜色(比如 box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25))。这类地方不会响应变量变化。
你需要额外补:
-
--bs-focus-ring-color(影响:focus-visible轮廓) -
--bs-emphasis-color(部分文字强调色,5.3.2 才加入,旧版需自己加) -
--bs-border-color(表格边框、分割线等,Bootstrap 5.3 默认没用变量,得自己替换) - 所有用到
rgba(..., 0.25)的地方,建议抽成--bs-opacity-25变量统一控制
否则你会看到:按钮变暗了,但点击后的蓝色外框还是刺眼亮色,或者表格线在暗色下几乎看不见。
最麻烦的不是写多少变量,而是记住哪些组件样式被 Bootstrap “绕过”了变量——它们藏在源码里,不报错也不提醒,只在暗色下悄悄露馅。


















