发布于 2026-01-06 3 阅读
0

深色模式:为什么以及如何使用。DEV 全球展示挑战赛,由 Mux 赞助:快来展示你的项目吧!

深色模式:为什么以及如何使用。

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

要想让你的产品在竞争中脱颖而出,你必须竭尽全力去打动用户,让他们成为你的客户。

背景

我提倡渐进增强,所以我认为为用户提供最佳体验至关重要。最近,Web 获得了一些强大的功能,可以帮助我们以全新的方式实现这一目标。我所说的强大功能,指的是用于处理用户偏好的全新 CSS 媒体查询。

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

目前这些媒体查询在约 80% 的浏览器中都能正常工作,这很棒。(来源:caniuse.com)因此,对于深色模式,我们需要首先关注配色方案。

偏好配色方案

首选配色方案媒体查询会从用户的操作系统设置中获取配置。因此,如果用户偏好较暗的界面,网站可以调整其设计以符合这一偏好。

Adam Argyle 在 2019 年 Chrome 开发者峰会上出色地讲解了这项技术的工作原理以及我们为什么要使用这些媒体查询。

这是视频,我建议您完整观看,但如果您只对新媒体查询感兴趣,请跳到 4:10,或跳到下面的下一部分。

即将推出

网络上即将出现一系列新的用户偏好,这将从根本上改变网页设计的方式。

@media (prefers-contrast: high){}
@media (prefers-reduced-transparency: reduced){}
@media (forced-colors: high){}
@media (light-level: dim){}

通过这些新设置,我们可以将用户偏好设置结合起来,为我们的每个用户提供绝对最佳的设计。

根据当前光线强度调整文本对比度,尊重用户对链接颜色的选择,在低端设备上移除造成干扰或性能问题的透明效果……等等等等。真是令人兴奋!

谁想要深色模式

5% 的用户已完成配置并准备就绪

我们开始追踪浏览网站时使用深色模式的用户数量。我们使用 Google 代码管理器中的自定义脚本来实现这一点,该脚本使用了 matchMedia JavaScript API。我们发现大约 5% 的用户已经配置好并准备就绪。

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode use recorded
}

考虑到prefers-colour-scheme媒体查询的支持将会不断增长,我们决定为这些即将推出的用户偏好样式奠定基础,并将它们直接融入到网站 CSS 的编写方式中。

所有支持媒体查询的浏览器都提供 CSS 自定义属性,因此我们可以利用这些属性轻松地为任何用户逐步增强用户体验。

我们采用现有的设计系统颜色,并在现有调色板的基础上添加新的变化,以降低饱和度并在需要的地方进行着色。

然后,在应用样式时,我们使用 CSS 自定义属性作为颜色的主要设置,但同时也使用 SASS 变量进行辅助,就像 body 标签上的这个例子一样。


$white:             #ffffff;
$chrome:            #f2f2f2;
$dark-chrome:       #4a4a4a;
$jet-black:         #111111;
$pale-purple:       #9387d8;
$electric-purple:   #604dd5;

:root{
    --body-color: #{$white};
    --text-color: #{$dark-chrome};
    --text-color-accent: #{$electric-purple};
}

.dark-mode {
    --body-color: #{$jet-black};
    --text-color: #{$chrome};
    --text-color-accent: #{$pale-purple};
}

body {
  background: $white;
  background: var(--body-color);
}

因此,当不支持 CSS 自定义属性的浏览器访问此页面时,它将回退到默认颜色设置。在本例中,默认颜色设置是浅色方案。

对于支持此代码的浏览器,它们默认会加载浅色样式。但我们特意避免在代码中使用媒体查询,为什么?

我希望允许用户切换深色主题的开关,所以在这个例子中,我们通过dark-mode给 body 添加一个类来应用主题,暂时避免使用媒体查询。

检测 Vue 中的深色模式

利用 App.vue 中的 mounted 生命周期,我们可以添加一个函数来检测prefers-color-scheme何时设置为深色模式,并将我们的类应用dark-mode到 body 元素上以更新 CSS 自定义属性,从而让层叠样式表完成大部分工作。

<script>
export default {
  mounted() {
      const darkMode = window.matchMedia("prefers-color-scheme: dark");
      if(darkMode) {
          document.body.classList.add('dark-mode')
      }
  }
}
</script>

通过在组件中使用精心设计的 CSS 自定义属性集,这一个设置就可以控制整个页面的外观。

为深色模式进行设计

对我来说,最大的挑战在于如何找出现有设计系统在哪些方面无法满足我的需求。我发现需要引入一些新的颜色才能使设计方案可行。

这些颜色分别是pale-purplealmost-blacklight-black。是的,给东西命名真的很难,但我们已经有深灰色了。

添加新颜色后的调色板。

在浏览器中进行设计

大多数网站都已经设计成浅色背景,所以很容易称之为浅色设计,你看,你已经成功了一半了。

现在我们可以根据用户的喜好定制网站的外观,从而确保用户看到适合他们的设计。

为了开始设计我的暗黑模式设置,我使用 Vue-CLI 构建了一个原型首页,其中包含了我们首页上的所有组件。这为我提供了一个可以进行调整的起点。哦,如果你还没猜到的话,我非常喜欢在浏览器中进行设计。

如果你还没猜到的话,我非常喜欢在浏览器中进行设计。

以下是当时首页的一小段内容。我根据我们的设计系统更新了项目符号的勾选标记,并将勾选标记挖空。

灯光设计主页。

更换背景和文字颜色对营造氛围大有裨益。主要的行动号召紫色在两种颜色下都非常醒目,因此无需做太大改动,但我稍微降低了饱和度,这种变化在切换主题时几乎难以察觉。

我更改的是标题的强调色。我使用了原有紫色的低饱和度色调,以避免它与黑色背景冲突,就像这样……🤮

深色背景上的亮色不协调。

除了降低文本强调色的饱和度之外,我还给首页主图中的汽车图片添加了一层淡淡的光晕。这并非最佳方案,但目前网站使用的 PNG 图片原本并非为深色背景而设计,因此边缘略显粗糙。添加光晕可以稍微柔化边缘,让我们有机会在逐步更新图片之前先推出这些更改。

深色系设计首页。

按照上述方法更换颜色时,我从背景中最深的颜色开始,逐步使用更浅的前景颜色。

深色系设计横幅。

这与当前设计中颜色分层的方式相反,如图所示。

轻量级设计横幅。

深色模式 SVG

你可能已经注意到,这些图片中的城市景观背景并没有像网站其他部分那样变化。你说得对,这让我非常恼火。

圣诞假期期间,我花了一些时间研究如何将我的新颜色应用到我的 SVG 文件中。

我真的很想为特定主题添加一些独特的元素,作为一点小小的点缀。想想看,深色模式下的月亮和星星,或者浅色模式下的小鸟?这是一种很酷的方式,可以为我们的设计增添个性。

我以 Figma 中的原图为基础,创建了一些我认为效果可能不错的颜色变体。

原创艺术作品。

我曾考虑过在前景建筑上添加亮着的灯光,但后来觉得这样太分散注意力,毕竟这些是背景图像。我还发现,在建筑上使用浅蓝色/紫色会让它们过于醒目,反而分散了人们对主要车辆图像的注意力。

深色模式的配色方案变化。

我尝试将它们置于几乎完全黑暗的环境中,只突出轮廓,仿佛月光反射在建筑物的边缘,只留下背景中摩天大楼的灯光。

SVG在深色模式下的最终设计。

确定方案后,我创建了一系列 CSS 类,并手动将 SVG 中的内联填充替换为这些类。

这些类用于控制SVG中路径的颜色和可见性。

.accent {
  fill: #6accb6;
}
.cloud {
  fill: #333333;
}
.dark-mode .cloud {
  fill: #211e28;
}
.skin{
  fill: #ffffff;
}
.foreground {
  fill: #ffffff;
}
.dark-mode .foreground {
  fill: #151416;
}
.foreground-shadow {
  fill: #c9d3ff;
}
.dark-mode .foreground-shadow {
  fill: #101010;
}
.bg-color {
  fill: #edf1fe;
}
.dark-mode .bg-color {
  fill: #211e28;
}
.outline {
  fill: #333333;
}
.dark-mode .outline {
  fill: #4f4c56;
}
.dark-show {
  opacity: 0;
}
.dark-mode .dark-show {
  opacity: 0.5;
}

.dark-hide {
  opacity: 1;
}
.dark-mode .dark-hide {
  opacity: 0;
}

因为我对建筑物的轮廓颜色不太满意,所以在浏览器中进行了一些实时颜色调整,最终效果如下。它很微妙,与现有的配色方案融合得很好,并且仍然为首屏增添了不少特色。

最终版首页设计,包括深色模式下的 SVG 图形。

在线演示

如果您想在浏览器中体验这些设计,请随意,在线演示的链接在这里

文章来源:https://dev.to/benjwalsh/dark-mode-why-and-how-41op