深色模式不生效主因是prefers-color-scheme未被识别或触发,需先用matchMedia检测;推荐采用class模式+CSS变量+JS监听兜底策略。

深色模式不生效,大概率不是 CSS 写错了,而是 prefers-color-scheme 根本没被识别或没触发——尤其在 WebView、老旧浏览器或未正确配置的环境里,媒体查询常“静默失效”。
先确认 prefers-color-scheme 是否真正起作用
别猜,直接测:
- 在控制台运行:
console.log(window.matchMedia('(prefers-color-scheme: dark)').matches),看返回true还是false - 如果始终是
false,说明当前环境(比如 iOS WKWebView 或低版本 Android WebView)压根没把系统深色偏好透传给网页 - 注意:Chrome DevTools 模拟器能切 ≠ 真机 WebView 支持;部分容器默认禁用该特性
media 模式 vs class 模式:选对策略才有效
Tailwind 或原生 CSS 的 @media (prefers-color-scheme: dark) 默认走的是 media 策略,依赖操作系统级信号。但它在很多 App 内嵌 WebView 中不可靠。
- media 模式:适合纯网页,无需 JS 控制,但依赖系统支持(iOS ≥13 / Android ≥10 + WebView ≥84)
-
class 模式:更可控,手动在
上加class="dark",所有dark:xxx或.dark .xxx规则立即响应 - Tailwind 中启用 class 模式:在
tailwind.config.js改为darkMode: 'class'
CSS 规则写了却没生效?检查三件事
即使媒体查询命中,样式也可能被覆盖或忽略:
立即学习“前端免费学习笔记(深入)”;
-
优先级不够:比如你写了
body.dark p { color: white; },但页面里有.article p { color: black !important; },后者会赢 -
选择器范围太窄:只改了
body背景,但h1、.card、button等元素没配深色规则,它们就沿用默认浅色样式 -
伪类/内联样式干扰:
style="color: #333"或a:hover等规则可能绕过主题逻辑,需统一用变量或带前缀的选择器覆盖
推荐做法:CSS 变量 + class 切换 + JS 监听兜底
兼顾兼容性与可维护性:
- 在
:root定义变量:--text: #111; --bg: #fff;,再在.dark下重写:.dark { --text: #eee; --bg: #121212; } - 所有颜色用
color: var(--text); background: var(--bg);,避免硬编码 - JS 切换时同时更新 class 和 localStorage,并监听系统变化:
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ...) - 首次加载时,优先读 localStorage,其次 fallback 到系统偏好,最后默认浅色
基本上就这些。不复杂但容易忽略——重点不在“怎么写深色样式”,而在于“怎么让浏览器真把它当回事”。










