跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何实现网页黑夜模式深色主题切换_使用CSS变量var与媒体查询

最轻量可靠的深色主题方案是用 prefers-color-scheme 媒体查询配合 :root 中的 CSS 变量,无需 JS 切换类,自动响应系统设置,性能高、兼容好、易维护。 直接用
prefers-color-scheme
媒体查询 +
:root
中的 CSS 变量,是最轻量、最可靠、浏览器原生支持的深色主题实现方式。它不依赖 JS 切换类,也不需要手动注入样式或强制渲染,适配性好、性能高、可维护性强。 为什么不用 class 切换而用 CSS 变量? 类切换(如
body.darktheme
)适合需要 JS 主动控制、支持用户手动覆盖系统偏好、或需兼容老浏览器的场景;但如果你的目标是「响应系统设置自动切换」,CSS 变量配合媒体查询更干净:变量定义一次,所有用到的地方自动更新,没有 JS 执行延迟,也不用担心 class 漏加/多加/冲突。
prefers-color-scheme
是浏览器原生能力,2019 年起主流浏览器已全量支持(Chrome 76+、Firefox 67+、Safari 12.1+、Edge 79+) 变量写在
:root
下,天然全局可用,
color: var(--text-color)
比
body.darktheme p { color: #eee; }
更易复用和批量调整 无需监听
matchMedia
或操作 DOM,减少 JS 负担,避免 SSR 渲染与客户端不一致问题 如何用 :root + prefers-color-scheme 定义两套变量? 把颜色、背景、边框等可变属性统一抽成变量,在浅色和深色媒体查询中分别赋值。注意:必须在
:root
中定义默认值(浅色),再用媒体查询覆盖深色值——不能反过来,否则未匹配时变量会失效。
/* 默认(浅色)变量 */ :root { --bg-color: #fff; --text-color: #333; --border-color: #ddd; --card-bg: #f9f9f9; }

/ 深色模式覆盖 / @media (prefers-color-scheme: dark) { :root { --bg-color: #121212; --text-color: #e0e0e0; --border-color: #333; --card-bg: #1e1e1e; } }

/ 全局使用 / body { background-color: var(--bg-color); color: var(--text-color); transition: background-color 0.3s, color 0.3s; }

.card { background-color: var(--card-bg); border: 1px solid var(--border-color); }

关键点:
@media (prefers-color-scheme: dark)
必须写在
:root
外层,不能嵌套进选择器里;变量名保持语义化(如
--text-color
而非
--dark-text
),避免逻辑倒置。 立即学习 “ 前端免费学习笔记(深入) ”; 如何让深色模式也支持用户手动覆盖系统设置? 仅靠
prefers-color-scheme
无法让用户「强制深色」或「强制浅色」——它只读取系统偏好。若需提供手动开关,得引入 JS 控制一个自定义数据属性(如
data-theme="dark"
),再用属性选择器覆盖媒体查询: 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载
/* 默认按系统 */ :root { --bg-color: #fff; }

@media (prefers-color-scheme: dark) { :root { --bg-color: #121212; } }

/ 用户手动指定时优先级更高 / :root[data-theme="dark"] { --bg-color: #121212; } :root[data-theme="light"] { --bg-color: #fff; }

JS 切换只需一行:
document.documentElement.setAttribute('data-theme', 'dark')
。注意:此时要禁用媒体查询的自动响应,可在 JS 中先移除
prefers-color-scheme
的影响(比如加个
!important
覆盖规则,或用更具体的选择器)。 常见错误:变量没生效或切换卡顿 变量未生效通常是因为: 变量名拼错(
var(--bg-colour)
→ 应为
var(--bg-color)
) 媒体查询写在了
:root
内部(
:root { @media (...) {...} }
是无效语法) 没有给过渡属性加
transition
,导致颜色突变(尤其背景色) 某些元素用了内联
style
或高优先级
!important
,强行覆盖了
var()
深色切换卡顿往往源于大量重绘——避免对
body
直接设
background-image
或复杂渐变;把动画限制在
color
、
background-color
、
opacity
这类可 GPU 加速的属性上。 真正难的是边界情况:比如深色模式下 SVG 图标颜色怎么同步?表单控件(
input
、
select
)如何保持可读性?这些没法靠变量一劳永逸,得结合伪元素、
currentColor
或额外 class 单独处理。

相关文章