增加了暗黑模式

用了一段时间 iOS 的 dark mode 感觉良好,特别是夜间看手机不会很刺眼。周末给网站加了暗黑模式功能,检测用户设备对用户切换到暗黑模式,不需要插件,只要一小段js和css代码即可。

实现原理

  1. 通过js获取当前访问设备的主题色设置模式做判断给html页面增加样式;
  2. 利用增加的样式和css的自定义属性切换css属性值。

利用js代码获取当前访问设备的主题色设置模式,并在页面html的body标签上增加css类dark

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches{
document.querySelector("body").classList.add("dark")
};

其中,prefers-color-scheme CSS 媒体特性用于检测用户是否有将系统的主题色设置为亮色或者暗色,详情请见prefers-color-scheme

处理css样式:第一步,定义暗黑模式和正常模式下的css样式

.dark{ /*这里定义暗黑模式下的样式*/
--dark-background:#333;
--dark-color:#333;
}
:root{ /*root伪类定义正常模式下的样式*/
--normal-background:1px solid #e5e5e5;
--normal-color:1px solid #555;
}

处理css样式:第二步,修改暗黑模式下需要调整的css样式

这里需要用到var()函数的备用值功能来处理正常模式下的样式,否则在正常模式下获取不到样式。

.wrapper{
background:var(--dark-background,var(--normal-background));
color:var(--dark-color,#666);
color:#666;/*原有样式可保留使之兼容不支持css自定义属性的浏览器,如IE浏览器*/
}

什么是css自定义属性

自定义属性(有时候也被称作CSS变量或者级联变量)是由CSS作者定义的,它包含的值可以在整个文档中重复使用。

使用css自定义属性

css自定义属性使用起来非常简单和方便,如下:
由自定义属性标记设定值,如: --main-color: #000;
由var() 函数来获取值,如: color: var(--main-color);
以上效果等同于color:#000;
var() 函数可以定义多个备用值(fallback value),当给定值未定义时将会用备用值替换,语法为:

var( <custom-property-name> [, <declaration-value> ]? )

例如:color: var(--main-color,#999)即,当--main-color未定义或是为无效值时,取#999
color: var(--main-color,var(--main-color-b))即,当--main-color未定义或是为无效值时,取--main-color-b
灵活使用css自定义属性会来带意想不到的效果。
更多请见:使用CSS自定义属性(变量)

浏览器兼容性

本文用到的css自定义属性prefers-color-scheme均需注意浏览器兼容性问题,关于浏览器兼容性详情请见各自的文档说明:

  1. prefers-color-scheme
  2. 使用CSS自定义属性(变量)

发表评论

评论(9)

  1. 叶开楗 via Chrome 94

    也有用js插件的 哈哈!方便点。

  2. Yan via Chrome 94

    ps 不用cookie有个问题,刷新时会有一个闪烁。

    1. 秩秩斯干

      @Yan 确实是这样 👍👍👍

  3. Yan via Safari 15

    办法不错。我稍微改了一下,时间在22点到6点强制为黑色。

    1. 秩秩斯干

      @Yan 起因是上次在你那看到右下角有个小太阳切换,觉得好,决定弄一下。这个方法也不好变量搞多了影响性能。还是加载单独的样式文件比较好,弄了深色模式才发现比我想象的复杂,颜色不是简单变灰变黑那么简单,还有这里的logo深色模式下直接成另一种风格了。

      1. Yan via Chrome 94

        @秩秩斯干 确实比想象的要复杂,我昨晚就被你“害了”,调了半天,哈哈哈!

        逻辑:
        1、点小太阳时的权限最高。同时写入cookie。
        2、其次以21点到6点为准强制调成黑色。也写入cookie。
        3、最后其余时间参考系统的颜色模式。不写入cookie。

        1. 秩秩斯干

          @Yan 😄,高级啊 👍👍👍

  4. wys via Android

    现在没变过来呢?
    我也想弄一个,像mac里的word,下午一过就自动暗黑背景白色字了。

    1. 秩秩斯干

      @wys 您本地启用深色模式再刷新没变化吗,需要您本地启用深色模式才会切到深色模式。