bootstrap深色模式需手动设置并调用update(),prefers-color-scheme仅作初始建议和css变量条件,不自动触发切换。

prefers-color-scheme 媒体查询本身不能直接触发 Bootstrap 深色模式
浏览器的 prefers-color-scheme: dark 是一个只读信号,它不会自动给 加上 data-bs-theme="dark" —— Bootstrap 5.3+ 的深色模式**不依赖也不响应这个媒体查询自动切换**,它只是把该查询作为 CSS 变量定义的条件之一(比如在 @media (prefers-color-scheme: dark) 里设置 --bs-body-bg)。所以光写媒体查询,不设属性,组件不会变暗。
必须配合 data-bs-theme 属性才能让组件真正响应
Bootstrap 所有组件(btn、card、form-control 等)的深色样式,只认 这个根级属性。CSS 内部靠 [data-bs-theme="dark"] 和 @media (prefers-color-scheme: dark) **双重规则**生效,但前者是开关,后者只是兜底或初始值来源。
- 漏掉
document.documentElement.setAttribute('data-bs-theme', 'dark'),哪怕媒体查询匹配了,按钮背景、卡片边框等仍保持亮色 - 只改
或某个<div> 的 <code>data-bs-theme,Toast、Offcanvas等挂载到document.body外的组件可能不响应 - SSR 场景下,服务端必须输出
(不能猜偏好),JS 加载后才根据matchMedia结果补设并调用bootstrap.Theme.getOrCreateInstance().update() - 页面加载时优先读
localStorage.getItem('theme'),有值就直接设data-bs-theme并调.update() - 没值时再 fallback 到
window.matchMedia('(prefers-color-scheme: dark)').matches,转成字符串'dark'或'light'存入 localStorage - 监听系统偏好变化:用
matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ...),但仅在用户未手动切换过时才同步更新(可存一个themeMode: 'auto' | 'light' | 'dark'标记) - 别在 CSS 里写
html[data-bs-theme="dark"] { --bs-body-bg: #212529; }后又加@media (prefers-color-scheme: dark) { :root { --bs-body-bg: #121212; } }—— 后者会覆盖前者,导致手动切换失效 - 确认引入的是完整 Bootstrap CSS(如 BootCDN 上的
bootstrap.min.cssv5.3.3+),精简版或旧版不含_variables-dark.scss编译结果 - 检查开发者工具中
:root下的--bs-body-bg是否随data-bs-theme改变而变化;若不变,说明变量定义被后续 CSS 干掉了 - 禁止在自定义 CSS 中写死颜色:
.card { background: white; }必须改为.card { background: var(--bs-body-bg); } - 如果用了 Sass 自定义构建,确保
$enable-dark-mode: true已启用,并 import 了scss/mixins/_color-mode.scss
如何安全地用 prefers-color-scheme 初始化主题
把它当做一个“默认建议”,而不是最终决定。用户手动切换过主题后,应以 localStorage 为准,避免系统设置变化导致覆盖用户选择。
常见失效原因:CSS 加载顺序与硬编码颜色
即使 data-bs-theme 正确、.update() 也调了,组件还是不暗,大概率是 CSS 覆盖问题。
data-bs-theme 没设在 上、.update() 忘调、或者某一行 background: #fff 直接把变量值焊死了。











