使用 @media (prefers-color-scheme) 需显式声明 dark/light 规则对,CSS 变量应在各媒体查询内完整重定义,JS 须用 matchMedia().addEventListener('change') 监听切换,并为不支持环境提供三层 fallback。
如何用
检测系统主题并生效
直接写
是最基础的入口,但它不会自动“同步”你的 CSS 变量或覆盖所有样式——必须显式声明每条规则。浏览器只按匹配的媒体查询块执行其中的声明,不继承、不回退、不智能合并。
常见错误是只在
块里改背景色,却忘了重置文字颜色、边框、阴影等依赖对比度的属性;或者把整套深色样式堆在同一个块里,导致维护困难。
必须成对定义:有
就该有对应的
(哪怕只是重置)
不要依赖级联顺序“覆盖”,而是用媒体查询块明确控制作用域
的值只有
、
、
三种,没有
或
在 Chrome DevTools 的 Rendering 面板里可手动切换模拟,但 iOS Safari 需真机验证(部分旧版不支持
)
CSS 自定义变量(
)配合媒体查询的正确写法
把主题色抽成 CSS 变量本身没错,但很多人误以为只要在
里定义一次、再在媒体查询里修改,就能全局响应——其实变量作用域取决于声明位置,
中的初始值不会被媒体查询里的同名变量“覆盖”,而是被“重新声明”为该块内的局部值。
真正可靠的做法是:在每个媒体查询块内完整声明你用到的所有相关变量,并确保它们出现在使用这些变量的选择器之前(CSS 自上而下解析)。
立即学习
“
前端免费学习笔记(深入)
”;
注意:上面写法可行,是因为两个
声明位于同一层作用域;若把
块写在
外部(比如放在某个组件类后面),变量可能未定义就已被使用。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
JavaScript 如何监听主题变化并触发逻辑
仅靠 CSS 媒体查询无法触发 JS 行为(比如加载深色图标、上报用户偏好、初始化 canvas 颜色),必须用
主动监听。
不能只调用一次
判断当前状态——那只是快照
必须用
监听动态切换(如 macOS 用户在设置里实时切主题)
首次执行时应主动调用 handler,避免首屏渲染和 JS 状态不一致
iOS Safari 13.4+ 才支持
事件;更老版本需轮询或降级为页面 reload
兼容性与 fallback:当
不可用时怎么办
不是所有环境都支持该特性:旧版 Edge、微信内置浏览器(X5 内核)、部分 Electron 应用默认禁用系统偏好读取。这时候单纯依赖 CSS 媒体查询会导致白屏、反色或不可读。
稳妥策略是「三层 fallback」:默认轻色 → JS 检测支持后挂载深色类 → 用户手动覆盖(如设置页开关)。CSS 层面至少保证默认样式可读,不依赖 JS 注入类名也能工作。
避免在
块外完全不定义关键颜色(比如只在
里设
,
下留空)
用
包裹高级用法(如深色模式下的
),防止不支持时解析失败
服务端渲染(SSR)场景下,无法直接读取客户端偏好,需通过 cookie / UA 特征或首屏 JS 注入 class 后重绘
最易被忽略的是打印样式表(
)与
的冲突——某些浏览器在深色系统下打印仍会强制使用深色背景,导致文字看不见。需要单独加
覆盖。
@media (prefers-color-scheme)@media (prefers-color-scheme: dark):darkprefers-color-scheme: darklightprefers-color-schemelightdarkno-preferenceautosystemno-preference--color-bg:root:root:root {
--color-bg: #fff;
--color-text: #333;
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #1e1e1e;
--color-text: #e6e6e6;
}
}
.card {
background: var(--color-bg);
color: var(--color-text);
}:root@media:rootwindow.matchMedia()matchMedia('(prefers-color-scheme: dark)').matches.addEventListener('change', handler)changeconst darkModeMedia = window.matchMedia('(prefers-color-scheme: dark)');
function handleThemeChange(e) {
document.documentElement.setAttribute('data-theme', e.matches ? 'dark' : 'light');
}
handleThemeChange(darkModeMedia); // 初始化
darkModeMedia.addEventListener('change', handleThemeChange);prefers-color-scheme@mediadarkbackgroundlight@supports (prefers-color-scheme: dark)filter: invert(1)@media printprefers-color-scheme@media print { ... }