一步步教你使用 SCSS 为网站添加暗黑模式

自从ios13发布之后,掀起了一股暗黑模式的潮流,近几年,各个主流操作系统都逐渐开始重视暗色模式,从而改善用户在环境光亮低时的阅读体验。以至于很长一段时间内,我都想给自己的网站添加一个暗黑模式的功能,这个暗黑模式应该与我目前的网站风格和样式不冲突并且和目前的颜色样式定义能相互配合使用,网站应该能够检测首选的配色方案并自动设置,并且应当支持切换。

那么,让我们开始吧。

1、创建配色方案

我们将配色方案定义到一个文件中,方便其他文件的引用。

$onyx: #404040;
$cultured: #f5f5f5;
...

由于这些颜色是静态的,我们需要将其转换为全局访问的CSS变量。这样,我们可以切换主题来实现颜色的切换。

html[data-theme="light"] {
          --color-text: #{$onyx};
          --color-background: #{$cultured};
        }
        
        html[data-theme="dark"] {
          --color-text: #{$cultured};
          --color-background: #{$onyx};
        }

上面,我们定义了两个主题,light和dark,两个主题中颜色和背景是相反的。

然后我们这样引用上面的变量

color: var(--color-text);
background: var(--color-background);

接下来就是在html中使用它了。

2、设置属性

我们使用如下js来做属性的设置:

document.documentElement.setAttribute('data-theme', 'dark');

这样设置之后,会显示暗黑模式的dark主题风格,我们增加一个复选框来实现light和dark的切换。

<input type="checkbox" name="theme_switch"/>

并为复选绑定切换事件:

document.querySelector('input[name=theme_switch]')
            .addEventListener('change', (cb) => {
              document.documentElement.setAttribute(
                'data-theme',
                cb.target.checked ? 'dark' : 'light'
              );

这样我们就实现了点击复选框做主题的切换功能。

3、自适应用户手机自动选择主题

我们使用下面代码判断用户手机是否是暗黑模式:

window.matchMedia('(prefers-color-scheme: dark)').matches

如果是暗黑模式,则返回true,否则返回false。好多小伙伴还不知道“prefers-color-scheme”,这里我们简单介绍一下。

prefers-color-scheme 是什么

W3C 在 2020 年 7 月 31 日发布的 Media Queries Level 5 标准草案 中提到了新的属性 prefers-color-scheme,网页现在可以通过条件规则组来获取浏览器宿系统的暗色模式状态并应用了。也就是说,现在我们可以很简单地实现“暗色模式系统访问的页面是暗色的,亮色模式系统访问的页面是亮色的”。

prefers-color-scheme 怎么用

可以参考 MDN 关于 prefers-color-scheme 的 描述

prefers-color-scheme 有 2 种值:

  • light——浏览器宿系统使用亮色主题的界面,同时也是默认值,浏览器 privacy.resistFingerprinting 被设置为 true 时返回的也将是这个值
  • dark——浏览器宿系统使用暗色主题的界面

还有一个已废弃的值:

  • no-preference——浏览器宿系统使用未知主题的界面,当较旧版本的浏览器在宿系统不支持系统层级的暗色模式时会返回这个值,较旧版本的浏览器 privacy.resistFingerprinting 被设置为 true 时返回的也将是这个值

通过条件规则组就可以作出判断。

完整的代码如下:

let checkbox = document.querySelector('input[name=theme_switch]');
        
        if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
          document.documentElement.setAttribute('data-theme', 'dark');
          checkbox.checked = true;
        } else {
          document.documentElement.setAttribute('data-theme', 'light');
          checkbox.checked = false;
        }
        
        // switch theme if checkbox is engaged
        checkbox.addEventListener('change', (cb) => {
          document.documentElement.setAttribute(
            'data-theme',
            cb.target.checked ? 'dark' : 'light'
          );
        });

最终效果如下:

点击预览:https://jsrun.net/qfUKp

版权声明:
作者:Miigua
链接:https://www.miigua.com/article/13.html
来源:米瓜的博客
文章版权归作者所有,未经允许请勿转载。

THE END
二维码
打赏
请在后台主题设置处设置打赏图片
< <上一篇
下一篇>>