基于@media (prefers-color-scheme: [dark|light])的暗黑与亮色主题切换

发布时间:2023年12月24日

今天有人反馈使用pdf.js的时候,发现pdf.js阅读器在自己的Mac Book电脑上显示的背景是暗黑色,而别人的电脑上却是白色:

在这里插入图片描述

根据这个问题,找到了pdf.js使用的view.css有段代码,类似这样:

@media (prefers-color-scheme: dark){
	--dialog-bg-color:#1c1b22;
}

@media (prefers-color-scheme: dark)这个是什么意思呢?

以前如果提到 CSS 的 @media ,可能的第一反应就是它是用来做屏幕查询的,但实际上@media的查询功能远超想象。本文就基于@media (prefers-color-scheme: dark)的暗黑主题切换设置进行说明:

说到主题切换,很多站点都会配置多套的CSS颜色,用作站点主题切换。大部分站点会在页面导航的右上角增加一个主题切换的 选择框,让用户进行主题选择切换。实现的方式是,配置不同颜色的var变量,在写css样式时,在代码中引入var变量,最后通过改变全局 :root 做到站点的主题切换。

var 配置:

:root{
  --background-color: #fff;
  --font-color: #000;
  --border-color: #eee;
}
css 使用:

body {
  backgroud-color: var(--background-color);
  color: var(--font-color);
  border-color: var(---border-color)
}

而如何跟随系统主题的设置进行主题颜色的匹配呢?这就需要用到prefers-color-scheme css 媒体特性。

在macOS系统中提出了dark和light两种视觉模式,即暗色(dark)和高亮(light)两种皮肤,而且这两种皮肤是系统级别的:

在这里插入图片描述

下面结合prefers-color-scheme css 媒体特性跟随系统主题的设置进行主题颜色的匹配:

prefers-color-scheme css 媒体特性:
用于检测用户是否有将系统的主题色设置为亮色或者暗色。

通过配置CSS的 @media ,我们就可以获取到系统的深色模式。

浅色模式:

@media (prefers-color-scheme: light) {
 ...
}

深色模式:

@media (prefers-color-scheme: dark) {
  ...
} 

除 light 和 dark 两个参数外,还有一个 no-preference 参数,配置此参数,则不会进行任何的系统模式查询。

接下来,我们结合@media、prefers-color-scheme、var进行一个简单背景色的切换的应用:

style.css:网站上普通样式(通用样式)

body {
  backgroud-color: var(--background-color);
}
dark.css:暗色系所需样式规则

@media (prefers-color-scheme: light) {
  :root {
    --background-color: white;
  }
}
light.css:亮色系所需样式规则

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: black;
  }
} 

然后我们可以使用<link media=""/>有条件的加载。

最后我们利用Caniuse,一起看一下这个特性目前的兼容性:

在这里插入图片描述

我们可以利用js来探测它的兼容性和监听它的变化:

// 检查用户是否偏好深色主题
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
 
// 监听变化
darkModeMediaQuery.addEventListener('change', () => {
  if (darkModeMediaQuery.matches) {
    console.log('主题已切换:用户偏好深色主题');
    // 在这里应用深色主题的样式或逻辑
  } else {
    console.log('主题已切换:用户偏好浅色主题');
    // 在这里应用浅色主题的样式或逻辑
  }
});
 
// 初始检查
if (darkModeMediaQuery.matches) {
  console.log('初始状态:用户偏好深色主题');
} else {
  console.log('初始状态:用户偏好浅色主题');
}

看一下效果,在亮色主题下执行以上代码,然后先后切换暗黑和亮色模式的结果如下:

在这里插入图片描述

文章来源:https://blog.csdn.net/q1003675852/article/details/135183858
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。