HTML如何实现暗黑模式_prefers-color-scheme配合方法

作者:袖梨 2026-06-29
直接用 @media (prefers-color-scheme: dark) 和 light 媒体查询可原生响应系统主题,无需JS;需在CSS中分别定义两套样式,避免!important破坏层叠,兼顾表单、SVG、阴影等细节,并注意Safari及WebView兼容性问题。

直接用 prefers-color-scheme 媒体查询就能响应系统级暗黑/亮色偏好,不需要 JS 监听或手动切换逻辑——前提是用户没在浏览器里强制覆盖系统设置。

如何用 @media (prefers-color-scheme) 写基础适配

这是最轻量、最符合语义的方案,CSS 原生支持,无 JS 依赖,页面加载即生效。

  • 必须写在 CSS 文件或 <style> 标签内,不能用内联 style 属性
  • 支持三个值:lightdarkno-preference(极少见,可忽略)
  • 浏览器按系统设置匹配,Windows/macOS/iOS/Android 都支持,Chrome 76+、Firefox 67+、Safari 12.1+
  • 示例:
@media (prefers-color-scheme: dark) {  body {    background: #121212;    color: #e0e0e0;  }  a { color: #bb8eff; }}@media (prefers-color-scheme: light) {  body {    background: #ffffff;    color: #333333;  }  a { color: #4285f4; }}

注意:两个规则可以共存,但不要用 !important 覆盖对方,否则会破坏层叠逻辑。

为什么加 data-theme 属性 + JS 是常见补充手段

因为 prefers-color-scheme 只能读系统偏好,无法应对用户主动点击「切换主题」按钮的需求。

立即学习“前端免费学习笔记(深入)”;

  • 典型做法:初始化时读取 matchMedia('(prefers-color-scheme: dark)').matches,设 <html data-theme="dark">
  • 后续所有主题样式都基于 [data-theme="dark"] 选择器,而非媒体查询 —— 这样 JS 切换才可控
  • 关键点:JS 设置后,必须同步调用 localStorage.setItem('theme', 'dark'),否则刷新丢失
  • 别漏掉监听系统变化:matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ...)

容易被忽略的兼容与细节问题

看似简单,但线上出问题往往卡在这几处:

  • Safari 13.1–14.0 对 @media (prefers-color-scheme) 的解析有 bug,嵌套在 @layer 或某些预处理器输出中可能失效,建议单独提一层写
  • 部分安卓 WebView(尤其旧版 QQ/微信内置浏览器)完全不支持该媒体查询,需 fallback 到 localStorage 检测
  • 不要只改文字和背景色:表单控件(<input><select>)、滚动条、box-shadow、SVG fill 都得一并调整,否则视觉割裂
  • 深色模式下慎用纯黑 #000000:OLED 屏幕易烧屏,推荐 #121212#1e1e1e

真正难的不是第一次适配,而是后续维护:每次新加组件,都要检查它在两种模式下的对比度、焦点态、禁用态是否可读可用。系统偏好只是起点,不是终点。

相关文章

精彩推荐