双栏布局的暗黑模式必须用 CSS 变量统一管理颜色、边框、阴影等值,通过 :root 定义 --bg-main、--bg-sidebar 等变量,由 body.dark 控制切换,结合 prefers-color-scheme 与 localStorage 实现自动适配与手动覆盖,并添加 will-change 和 transform: translateZ(0) 保障动画与滚动性能。

双栏布局的暗黑模式必须用 CSS 变量,不能靠写两套 class
双栏布局(比如 aside + main)在暗黑模式下容易出现颜色不一致、边框/阴影丢失、文字可读性骤降等问题——根本原因常是开发者给每个栏目单独写了 background 和 color,没抽离成变量。一旦切换主题,aside 换了色但 main 还卡在浅色,或者过渡动画只作用于 body 而漏掉侧边栏。
正确做法是把所有颜色、边框、阴影、文字对比度相关值全定义在 :root,再让双栏结构无条件继承:
-
--bg-main、--bg-sidebar、--border-subtle、--text-secondary等变量统一管理,避免硬编码#f5f5f5或rgba(0,0,0,0.05) -
aside和main的样式全部用var(--bg-sidebar)和var(--bg-main),而不是各自写死背景色 - 深色模式下
aside的分割线如果用border-bottom: 1px solid #eee,会直接消失——应改用var(--border-subtle),并在body.dark中设为rgba(255,255,255,0.08)
切换时只改 document.body.classList,别碰 aside 或 main 的 class
有人会给 aside 单独加 dark-mode 类,再写一堆 aside.dark-mode { ... } 规则——这破坏语义、增加选择器权重、且无法响应系统偏好变化。
真正轻量可靠的方案是:所有主题逻辑收束到 body 上,CSS 用层级选择器自然穿透:
- 默认状态:
body aside { background-color: var(--bg-sidebar); } - 深色状态:
body.dark aside { background-color: var(--bg-sidebar); }(变量值已在body.dark :root中覆盖) - 这样哪怕你后续加了
article、nav、footer,都不用改 JS,只要它们也用var()就自动适配
prefers-color-scheme 和用户手动切换必须共存,不能二选一
只靠 @media (prefers-color-scheme: dark) 会导致用户点了切换按钮却没反应;只靠 JS 切换又会让首次加载时闪白(尤其双栏内容多、图片大时)。两者必须协同。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
关键动作在页面初始化阶段就完成:
- 读取
localStorage.getItem('theme'),若为'dark',立即执行document.body.classList.add('dark') - 若为
null,再查window.matchMedia('(prefers-color-scheme: dark)').matches,按结果设置 class - 之后才绑定按钮事件:
document.getElementById('theme-toggle').addEventListener('click', () => { ... }) - 监听系统偏好变化:
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { ... }),但仅当用户未手动设置过主题时才响应
双栏布局的过渡动画容易失效,得锁住两个容器的 will-change
双栏常见问题:点击切换后,main 区域有淡入动画,aside 却瞬间跳变——因为浏览器对 var() 变化的重绘优化不一致,尤其涉及 box-shadow 或 background-image 时。
解决方法不是给每个元素加 transition,而是提前提示渲染引擎:
- 在 CSS 中统一加:
aside, main { will-change: background-color, color, box-shadow; } - 确保所有颜色相关属性都走
var(),不要混用rgb()或命名色(如lightgray) - 避免在
aside里用filter: brightness(0.95)模拟暗色——它不触发will-change优化,且和var()冲突
最易被忽略的是:双栏中如果有固定高度的 aside,且内部用了 position: sticky,深色模式下滚动时可能因颜色重绘不及时出现撕裂感——这时必须加 transform: translateZ(0) 强制 GPU 加速,而不是依赖过渡动画。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










