给网站添加暗黑模式指南

特别声明:小站已开通年费VIP通道,年费价格为 ¥365.00元。如果您喜欢小站的内容,可以点击开通会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)

给网站添加暗黑模式是随着macOS中的暗黑模式(Dark Mode)出现之后的一个热门话题,今年上半年在《如何使用CSS实现暗黑模式和高亮模式的切换》一文中就和大家一起聊了聊怎么通过CSS来实现暗黑模式和高亮模式切换。事实上,社区上有关于这方面的讨论也很多,都在围绕着怎么给网站添加暗黑模式。今天在这篇文章再次和大家一起聊聊这个已久的话题,不同的是,这篇文章将和大家从不同的角度来聊怎么给网站添加暗黑模式。感兴趣的同学,请继续往下阅读。

暗黑模式是系统级别的

所谓的暗黑模式并不是现在才有的,这个事实已经存在很久了。如果你很早就接触过电脑的话,你可能会发现你使用过的电脑屏幕经历过好几个过程,看起来会像下面这样:

是不是觉得既熟悉又陌生。既然如此,为什么今年会成为设计或者说Web端的一个热点呢?

其实这一切都应该归功于Apple公司,在macOS系统中提出了darklight两种视觉模式,即暗色(dark高亮(light两种皮肤,而且这两种皮肤是系统级别的,我们可以通过系统上的切换,让整个电脑上只要支持dark/light模式的应用都可以轻易切换。

那么为什么要从系统级别去做这个事情呢?这是有原因的。系统面对的用户群体中朋部分人士在身体上存有一定的缺陷,比如说色盲的用户群体。也就是说,这种暗黑模式或者高亮模式对于有色盲的用户群体是非常友好的。既然如此,为了让自己的Web网站或者Web应用能向系统级别靠齐,就有了网站级别的暗黑模式。

你可能在很多网站的右上角看到了一个提供暗黑和高亮模式的切换按钮。

暗黑模式实现原理

给Web网站或者Web应用添加暗黑模式的基本原理我想大家应该很清楚,事实上也非常的简单。

正如上图所示,给同一个Web网站或Web应用提供多套皮肤,用户根据自己的喜欢进行选择。那么给网站添加暗黑模式是同一个原理,就是给网站同时提供两套皮肤,即theme1.csstheme2.css

早期我们可能会借助于JavaScript脚本,根据用户的选择在一个<link />标签上进行两个主题文件(即.css文件)切换来实现:

<!-- HTML -->
<link type="text/css" rel="stylesheet" media="all" href="../theme1.css" id="theme_css" />

// Script
document.getElementById('buttonID').addEventListener('click', function(){                     document.getElementById('theme_css').href = '../theme2.css'; 
})

这可能是一种比较古老的实现方案。也是大家最为熟悉的方案。

CSS实现暗黑模式切换

时至今日,给Web网站或Web应用程序实现暗黑模式已有多种模式。可以是纯CSS的方式,也可以是CSS和JavaScript结合的模式。那么接下来,我们来看看具体的实现方式。

媒体查询prefers-color-scheme

CSS有一个特别强大的特性,那就是媒体查询@media,CSS的@media规则可以用于有条件地将样式应用于文档以及其他各种上下文和语言,如HTML和JavaScript。在W3C的Media Queries Level 5引入了“用户首选媒体特性”,即Web网站或应用程序检测用户显示内容的首先方式的方法

比如prefers-reduced-motion这个媒体查询就可以检测页面上的动画,假设设备开启了“Reduce motion”选项,就可以通过该媒体查询选项让页面上的元素是否具有动效:

如果用户开启减少动效的喜好,那么就不要在元素上使用动效:

@media (prefers-reduced-motion: reduce) {
    button {
        animation: none;
    }
}

如果用户没有在系统级别设置该选项的话,可以像下面这样让按钮有动效:

@media (prefers-reduced-motion: no-preference) {
    button {
        animation: vibrate 0.3s linear infinite both;
    }
}

Web上的其他具有动效的元素都可以像上面之样使用, 上面只是用button为例。

如果Web网站有很多元素具有动效的话,还可以将所有与动效相关的CSS放在一个独立的文件中,然后通过linkmedia属性来加载:

<link rel="stylesheet" href="animations.css" media="(prefers-reduced-motion: no-preference)" />

为了说明JavaScript如何控制preferences-reduced-motion。这里假设你在项目中使用了Web Animation API。当用户开启了偏好设置,CSS规则会被浏览器动态触发,这样一来我五一需要自己监听变化,然后手动停止与动画相关的东西:

const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
    console.log(mediaQuery.media, mediaQuery.matches);
    // ...
});

如果你有强迫症,强迫减少网站上所有有动效停下来,还可以像下面这样的简单粗暴的操作:

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001s !important;
        transition-duration: 0.001s !important;
    }
}

有关于prefers-reduced-motion更详细的介绍可以阅读@Thomas Steiner的博文《Move Ya! Or maybe, don't, if the user prefers-reduced-motion!》。

似乎上面的内容偏离了我们今天要聊的主题,大家不用着急。只不过是拿prefers-reduced-motion这个媒体查询来抛砖引玉而以。在CSS中通过媒体查询的prefers-color-scheme特性和prefers-reduced-motion类似,不同是,该特性是用于检测用户是否要求页面使用light还是dark主题。该媒体查询常见的值有:

  • no-preference:表示用户未指定操作系统主题。其作为 布尔值 时以false输出
  • light:表示用户的操作系统是浅色主题(light
  • dark:表示用户的操作系统是深色主题(dark

也就是说,通过prefers-color-scheme媒体查询要让暗黑模式(dark)开启深色系主题,可以像下面这样使用:

@media (prefers-color-scheme: dark) {
    :root {
        --background-color: #111416
        --text-color: #ccc;
        --link-color: #f96;
    }
}

当然在非dark模式下,你的样式可能像下面这样:

:root {
    --background-color: #fff;
    --text-color: #333;
    --link-color: #b52;
}

body {
    background-color: var(--background-color);
    color: var(--text-color);
}

a {
    color: var(--
剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/css/add-dark-light-mode-for-web.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部