根本原因不是浏览器“不支持”,而是 prefers-color-scheme 信号在传递链中被截断或忽略——从操作系统到 WebView,再到 CSS 引擎,任一环节缺失都会导致媒体查询始终返回 false。

根本原因不是浏览器“不支持”,而是 prefers-color-scheme 信号在传递链中被截断或忽略——从操作系统到 WebView,再到 CSS 引擎,任一环节缺失都会导致媒体查询始终返回 false。
为什么 window.matchMedia('(prefers-color-scheme: dark)').matches 总是 false
这是最直接的判断依据。如果它返回 false,说明系统偏好根本没透传进来,后续所有 CSS 都白写。
- iOS WKWebView 默认不启用自动主题适配,需原生层显式设置
webView.configuration.defaultWebpagePreferences.preferredContentAppearance = .dark或.automatic - Android WebView 版本低于 84(对应 Chrome 84)时,
prefers-color-scheme完全不可用;即使新版,也要确认容器是否调用了setForceDark(WebView.FORCE_DARK_ON) - 某些定制 ROM(如华为 EMUI、小米 MIUI)未向 WebView 暴露标准系统主题信号,或返回
no-preference - Electron 应用默认禁用该特性,需在
webPreferences中开启prefer-color-scheme选项
@media (prefers-color-scheme: dark) 写了但样式不生效
信号来了,但 CSS 没反应,问题通常出在结构或覆盖逻辑上。
- 媒体查询必须写在顶层 CSS 中,不能嵌套在其他
@media或@supports里——旧版 Safari(≤13.1)会直接跳过整个块 -
:root中的变量必须先声明浅色默认值,再在媒体查询内完整重写;漏掉任一变量(比如--border),深色下就会 fallback 到浏览器默认色 - 选择器优先级不够:比如
body { background: white }和@media (prefers-color-scheme: dark) { div.content { background: black } },后者无法覆盖前者,因为div.content特异性 ≠body - 内联样式或 JS 直接操作
element.style.color会压倒所有 CSS 规则,包括媒体查询
为什么 Safari 深色模式下表单控件仍是白底
这不是你的 CSS 没写对,而是浏览器 UA 控件没被触发变色逻辑。
立即学习“前端免费学习笔记(深入)”;
- 仅靠
html { color-scheme: light dark }不够,必须加<meta name="color-scheme" content="light dark">到<head>—— 这是 iOS Safari 和多数 WebView 的硬性开关 -
color-scheme只影响原生控件(<input>、<select>、滚动条、Canvas 边框等),不影响你写的background-color或color - 系统语义色如
Canvas、CanvasText才能真正响应高对比度/深色模式,硬写#121212会丢失这些动态适配能力
最容易被忽略的是:媒体查询只在页面加载时读取一次系统偏好,切换系统主题后不会自动重绘——真机调试时别只看 DevTools 模拟器,得关掉再重开页面验证;而 WebView 环境里,甚至要重启整个 App 才能重新获取信号。


















