最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何用CSS实现深色模式切换的基础样式?
时间:2026-09-01 19:42:47 编辑:袖梨 来源:一聚教程网
必须将所有CSS自定义变量声明在:root中,因为只有html根元素能确保所有后代(包括原生控件和Shadow DOM)通过继承正确获取变量值;其他选择器作用域受限,且@media(prefers-color-scheme:dark)须后置声明并配合class切换逻辑。
必须把所有变量声明在 :root 里,否则 input、select 等原生控件和 Shadow DOM 内部根本拿不到值。
为什么 :root 是唯一安全的锚点
CSS 自定义属性靠继承传播,而只有 :root(即 <html> 元素)能确保任意后代节点通过 var(--bg-color) 正确取值。写在 .dark、body 或组件类里,变量只对该选择器及其后代生效。
-
.dark { --bg-color: #121212; }→<input>若没被包裹进.dark,就 fallback 到透明或浏览器默认色 -
body { --text-color: #eee; }→var(--text-color)在<html>上求值时根本找不到定义 - Shadow DOM 内部不继承外部
:root变量,须在:host或::slotted里手动传入
@media (prefers-color-scheme: dark) 必须后置且不嵌套
它只负责系统偏好兜底,不是万能开关。写错位置或漏声明变量,一刷新就崩。
- 必须放在所有
:root默认声明之后,否则旧版 Safari 直接忽略 - 所有变量必须先在
:root中完整声明默认值,否则系统设为no-preference时var(--border-color)会 fallback 成transparent - 不能只覆盖部分变量:漏了
--shadow-sm,用了box-shadow: var(--shadow-sm)的按钮就没了阴影 - 禁止嵌套:
@media (max-width: 768px) { @media (prefers-color-scheme: dark) { } }是无效结构
手动切换时 JS 只改 class,别碰 style.setProperty()
后者会废掉整套媒体查询逻辑,且维护爆炸。
- ✅ 正确做法:
document.documentElement.classList.toggle('dark') - ❌ 绝对避免:
document.documentElement.style.setProperty('--bg-color', '#121212') - 初始化必须早于首屏渲染:在
<script>标签内直接执行,别等DOMContentLoaded - 同步持久化:
localStorage.setItem('theme', newTheme)和classList必须一起做,缺一不可 - 检查 class 名是否匹配 CSS 中的
:root.dark:JS 切dark但 CSS 写.dark就失效
最容易被忽略的是:变量作用域一旦锚定在 :root,后续所有组件样式都只能靠继承和重声明来响应,没有中间层可绕过——写错一处,input、button、textarea 全线失焦。