@media (prefers-color-scheme: dark) 是实现系统级暗黑模式最直接轻量的方式,但需配合 CSS 变量、正确声明顺序、兜底逻辑及 JS 初始化,否则易白屏、闪动或失效。

用 @media (prefers-color-scheme: dark) 是实现系统级暗黑模式自动切换最直接、最轻量的方式,但它必须配合 CSS 变量 + 正确的声明顺序 + 兜底逻辑,否则容易白屏、闪动、错色或在旧浏览器失效。
基础写法:变量定义 + 媒体查询覆盖
所有主题色必须先在 :root 中定义默认值(以浅色为基准),再在媒体查询中完整覆盖。不能只写暗色分支,也不能把变量定义在组件里。
-
正确示例:
:root {<br> --bg: #ffffff;<br> --text: #333333;<br> --border: #e0e0e0;<br>}
@media (prefers-color-scheme: dark) {<br> :root {<br> --bg: #121212;<br> --text: #e0e0e0;<br> --border: #333333;<br> }<br>} -
使用时务必加 fallback:
background: var(--bg, #ffffff);,避免变量未定义导致样式崩塌 - 深色规则要放在浅色规则之后,否则可能被后续无条件样式覆盖
绕过首屏闪屏和兼容性问题
仅靠媒体查询会因浏览器解析时机晚而出现“先亮后暗”的闪屏,尤其在 iOS Safari 和微信 WebView 中明显。需 JS 初始化配合。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 页面加载时立即读取
matchMedia('(prefers-color-scheme: dark)').matches,并同步设置document.documentElement.setAttribute('data-theme', 'dark') - 用
[data-theme="dark"]选择器写高优先级规则,作为媒体查询的补充或降级方案 - 对不支持
prefers-color-scheme的旧浏览器(如 Safari 12.0、部分 Electron 内核),fallback 到时间判断或 localStorage 记录的用户偏好
原生控件和特殊元素也要适配
CSS 变量对 <input>、<select></select>、滚动条、<svg></svg> 的 fill/stroke 无效,它们不读取自定义属性。
立即学习“前端免费学习笔记(深入)”;
- 在
:root或html上加color-scheme: light dark;,这是告诉浏览器“我支持双模式”,让表单控件、滚动条、canvas 边框等自动响应系统色 - 对
::-webkit-scrollbar、input[type="range"]等需单独写暗色样式,例如:input { background: Canvas; color: CanvasText; } - SVG 图标建议用
currentcolor或内联fill="currentColor",使其继承文本色,随主题自动变化
避免第三方组件库颜色冲突
Ant Design、MUI、Chakra UI 等库常通过 JS 注入 class 或修改 :root 变量来切主题,与你的媒体查询规则直接打架。
- 统一用
[data-theme="dark"]作为最高优先级信号,覆盖关键样式,例如:[data-theme="dark"] .ant-btn { background: var(--btn-bg-dark); } - 不要对
:root直接加!important,否则库的 JS 更新会失效 - 检查文档是否要求额外引入深色主题 CSS 文件(如 Chakra 的
css-reset)

















