网页也懂黑夜与白天:系统主题自动切换

前言

不知道大家有没有遇到过,网页会根据系统设置的外观模式,显示不同的主题样式。这是如何实现的呢?

1、核心原理:认识 prefers-color-scheme 媒体查询

CSS原生媒体特性 prefers-color-scheme 是实现主题自动切换的核心,它能检测用户操作系统(Windows、macOS、iOS、Android 等)的主题设置,返回三个可能值:

  • light:用户设置浅色主题
  • dark:用户设置深色主题
  • no-preference:用户未设置(默认按浅色处理)

能覆盖绝大多数现代设备,无需额外 JS 即可实现基础切换。

2、案例实现

2.1 定义浅色主题

先在:root中定义浅色主题的基础变量:

css 复制代码
@media(prefers-color-scheme: light) {
    :root {
        --bg-color: #ffffff;
        /* 浅色背景 */
        --text-color: #333333;
        /* 浅色文字 */
    }
}

2.2 定义深色主题

通过 @media (prefers-color-scheme: dark) 覆盖深色主题的变量:

css 复制代码
@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #121212; /* 深色背景(避免纯黑) */
    --text-color: #e5e7eb; /* 浅色文字(避免纯白) */
  }
}

2.3 页面使用

在页面样式中统一使用 CSS 变量,无需重复编写明暗逻辑:

如何监听系统模式的变化:可以监听prefers-color-scheme: dark的变化,当matches为true时,为深色模式。

js 复制代码
 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {});
js 复制代码
body {
  background-color: var(--bg-color);
  color: var(--text-color);
  font-size: 16px;
}

可以在谷歌浏览器中设置切换:

效果如下:

深色:

浅色:

3、如何简写

上面的写法稍微有点复杂,可以使用CSS 的 color-scheme和 light-dark()函数 ,来实现 根据系统主题(深色/浅色模式)自动切换背景和文字颜色​ 的效果。

js 复制代码
:root {
    color-scheme: light dark;
}

body {
    background-color: light-dark(#ffffff, #121212);
    color: light-dark(#333333, #e5e7eb);
    font-size: 16px;
}

告诉浏览器和操作系统,这个网页 支持浅色(light)和深色(dark)两种主题模式 ,CSS新增的 light-dark()函数 ,允许你 在一个声明里同时为浅色模式和深色模式定义颜色。

4、用户手动切换主题

虽然系统自动切换已满足大部分需求,但提供手动切换按钮能提升灵活性,核心思路是通过 JS 覆盖 CSS 变量,步骤如下:

  1. 添加切换按钮:
css 复制代码
theme-toggle">切换深色模式</button>
  1. 编写 JS 逻辑:
ini 复制代码
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;
// 初始化:根据系统主题设置按钮文本
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
themeToggle.textContent = isDark ? '切换浅色模式' : '切换深色模式';
// 切换主题
themeToggle.addEventListener('click', () => {
  const isCurrentlyDark = html.classList.contains('dark');
  if (isCurrentlyDark) {
    html.classList.remove('dark');
    themeToggle.textContent = '切换深色模式';
  } else {
    html.classList.add('dark');
    themeToggle.textContent = '切换浅色模式';
  }
});
  1. 补充 CSS 样式:
css 复制代码
/* 手动切换深色模式时的样式覆盖 */
:root.dark {
  --bg-color: #121212;
  --text-color: #e5e7eb;
}
/* 优先级:手动切换 > 系统主题 */
@media (prefers-color-scheme: dark) {
  :root:not(.dark) { /* 未手动切换时,遵循系统主题 */
    --bg-color: #121212;
    --text-color: #e5e7eb;
  }
}

总结

最后总结一下:系统主题自动切换的核心是通过 CSS 原生 prefers-color-scheme 媒体查询,结合 CSS 变量实现网页系统明暗主题自动切换。

相关推荐
IT_陈寒44 分钟前
Redis内存暴涨,没想到是AOF重写捣的鬼
前端·人工智能·后端
ikoala44 分钟前
让 Codex 自己查账:一个省 token 的小技巧
前端·后端·ai编程
ikoala1 小时前
AI 写页面像说明书,修 Bug 像贴膏药?把这两句话写进 AGENTS.md
前端·javascript·ai编程
去伪存真3 小时前
AI Agent Harness 深度测评与技术选型实战
前端·agent
FRing036 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
疯华整猫9 小时前
被杀掉之后:我把 Android 的「唤起 + 常驻」重做了一遍
前端·面试·架构
IT_陈寒11 小时前
Java开发实战:从入门到精通
前端·人工智能·后端
风骏时光牛马11 小时前
生成一个AI转岗经历标题,只需要一个标题,不需要其他的任何文本。
前端
Csvn20 小时前
Monorepo
前端
Csvn20 小时前
流水线
前端