一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何用CSS实现深色模式切换的基础样式?

时间:2026-09-01 19:42:47 编辑:袖梨 来源:一聚教程网

必须将所有CSS自定义变量声明在:root中,因为只有html根元素能确保所有后代(包括原生控件和Shadow DOM)通过继承正确获取变量值;其他选择器作用域受限,且@media(prefers-color-scheme:dark)须后置声明并配合class切换逻辑。

必须把所有变量声明在 :root 里,否则 inputselect 等原生控件和 Shadow DOM 内部根本拿不到值。

为什么 :root 是唯一安全的锚点

CSS 自定义属性靠继承传播,而只有 :root(即 <html> 元素)能确保任意后代节点通过 var(--bg-color) 正确取值。写在 .darkbody 或组件类里,变量只对该选择器及其后代生效。

  1. .dark { --bg-color: #121212; }<input> 若没被包裹进 .dark,就 fallback 到透明或浏览器默认色
  2. body { --text-color: #eee; }var(--text-color)<html> 上求值时根本找不到定义
  3. Shadow DOM 内部不继承外部 :root 变量,须在 :host::slotted 里手动传入

@media (prefers-color-scheme: dark) 必须后置且不嵌套

它只负责系统偏好兜底,不是万能开关。写错位置或漏声明变量,一刷新就崩。

  1. 必须放在所有 :root 默认声明之后,否则旧版 Safari 直接忽略
  2. 所有变量必须先在 :root 中完整声明默认值,否则系统设为 no-preferencevar(--border-color) 会 fallback 成 transparent
  3. 不能只覆盖部分变量:漏了 --shadow-sm,用了 box-shadow: var(--shadow-sm) 的按钮就没了阴影
  4. 禁止嵌套:@media (max-width: 768px) { @media (prefers-color-scheme: dark) { } } 是无效结构

手动切换时 JS 只改 class,别碰 style.setProperty()

后者会废掉整套媒体查询逻辑,且维护爆炸。

  1. ✅ 正确做法:document.documentElement.classList.toggle('dark')
  2. ❌ 绝对避免:document.documentElement.style.setProperty('--bg-color', '#121212')
  3. 初始化必须早于首屏渲染:在 <script> 标签内直接执行,别等 DOMContentLoaded
  4. 同步持久化:localStorage.setItem('theme', newTheme)classList 必须一起做,缺一不可
  5. 检查 class 名是否匹配 CSS 中的 :root.dark:JS 切 dark 但 CSS 写 .dark 就失效

最容易被忽略的是:变量作用域一旦锚定在 :root,后续所有组件样式都只能靠继承和重声明来响应,没有中间层可绕过——写错一处,inputbuttontextarea 全线失焦。

热门栏目