深色模式切换完全指南
深色模式切换完全指南
我最初将这篇文章发表在我的网站上。
您可能已经注意到,深色模式越来越受欢迎。本文将提供一份完整的指南,指导您如何在网站上添加深色模式。
开启黑暗面的最佳实践
最近,CSS-Tricks 的 Chris Coyier 向所有准备“撰写关于暗黑模式的博客文章”的人发起了挑战。他列出了需要涵盖的 10 个要点:
- 解释深色模式
- 提供演示(跳转至演示)
- 解释一下,深色模式本身就可以在操作系统层面实现。
- 展示 JavaScript 如何了解操作系统级别的选择
- 让用户对颜色偏好拥有最终决定权
- 构建一个主题切换器,包括一些注意事项
- 看看还有哪些人在开发深色模式切换功能
- 看看还有哪些人写过这篇文章。
- 讨论哪些内容受支持,哪些内容不受支持。
- 将无障碍设计作为首要考虑因素
本文旨在涵盖所有十个要点(有些要点比其他要点更突出)。我将分享我总结的实现深色模式切换的最佳实践,并期待根据社区的建议、批评和评论来完善这些实践。
运算顺序
- UI/UX 考量
- 使用 CSS 自定义属性定义深色/浅色 UI
- 使用 JavaScript 切换深色/浅色模式
- 尊重操作系统级别的配色方案偏好(并允许用户覆盖该偏好)
UI/UX 考量
让我们先明确一下术语。
-
深色模式
-
通常使用较深色调的用户界面
-
浅色模式
-
一种由来已久但并非亘古不变的默认设置,即用户界面使用较浅的调色板。

深色模式?苹果 IIe 和 Bank Street Writer,作者:Mark Mathosian
尽管有些人大力支持深色模式,但并非所有人都认为它优于其他模式。对两种模式的偏好完全取决于个人喜好。用户甚至可能在一天中的不同时间或根据所处位置选择不同的模式。比如,你躺在床上浏览 Reddit,而你的伴侣正试图入睡,却抱怨你 32 英寸笔记本电脑的屏幕太亮。这时你只需切换模式,我的天哪,深色模式又一次拯救了婚姻。
无障碍
在深色和浅色调色板之间切换不仅仅是简单地切换深色和浅色背景。最重要的是,您需要确保两种调色板中的颜色都符合无障碍对比度要求。许多颜色在不同模式下无法互换。这意味着您可能需要为每个调色板使用不同的主色或品牌色。
第二个需要考虑的因素是视觉层级。根据 Chethan KVS 关于设计深色主题的优秀文章(该文章本身基于 Material Design 的原则),其要点是:较深的色调应该用于页面底层,而越靠近页面前端则使用越浅的色调。例如,为了表明模态框位于页面顶部,其背景色应该比其下方区域的背景色更浅。
根据这些指导原则,我发现以下策略对于构建深色和浅色调色板很有用。
表面颜色
首先确定网站的表面颜色,可以包含三种或更多种由浅至深的色调。这些颜色将作为网站主体、菜单、页脚、导航栏、模态框等的背景色。
元素颜色
对元素颜色也采用同样的方法,元素颜色可能包含三种或更多种由深到深的色调。元素颜色指的是字体颜色、水平线、边框、表格以及任何其他需要与背景区分开来的元素。关键在于确保背景和文本的组合在适当的地方满足对比度要求。
标志性颜色
最后,选择你的主色、辅助色等等。再次强调,如果这些颜色要用作字体颜色,请确保它们在所有背景颜色上都保持足够的对比度。

使用 CSS 自定义属性定义深色/浅色 UI
不错。你现在拥有了一些漂亮的深浅色调配色方案。你可能在想:“我最好开始准备年度最佳配色方案奖的获奖感言了。” 如果你的配色方案还没达到完美,市面上有很多配色工具可以帮你。我特别喜欢的三个工具分别是Tailwind 的阴影生成器、Material Design 的调色板生成器以及ColorSpace 的调色板和渐变生成器。
盛装打扮却无处可去
但现在该怎么办?如何让你的调色板在你的网站上正常显示?
CSS 自定义属性允许您在 CSS 中定义变量。通过为深色和浅色调色板使用相同的属性名称,您和您的用户就可以在不同的色彩模式之间切换。
由于自定义属性仅限于定义它的选择器,最佳实践通常建议将所有属性定义在伪选择器下,:root以便变量可以全局访问。要区分浅色调色板和深色调色板是否处于活动状态,可以使用颜色模式自定义属性选择器,我们可以使用 JavaScript 来定位它。

使用 CSS 自定义属性定义深色和浅色调色板
使用 JS 切换深色/浅色模式
调色板已经定义好了,它们也存在于样式表中。但是目前还没有任何效果!
定义您的默认值
我们需要通过在标签上编写自定义属性来告诉文档应该处于哪种模式html。我们将编写一个函数,允许用户在深色模式和浅色模式之间切换,但首先需要为网站定义一个默认模式。网站应该以深色模式还是浅色模式加载?这个选择将由您决定,或许还需要一些用户调研。下面的标记展示了如何设置默认颜色模式。

在 HTML 中设置默认调色板
创建颜色模式切换按钮
用户需要点击才能切换模式。目前有很多巧妙的实现方式,例如在状态之间添加炫酷的 动画效果 或使用自定义图标。本文将采用更常规的方式,交替使用太阳和月亮两个图标分别代表浅色模式和深色模式。(本文中引用了 SVG 图标。)use

浅色和深色模式按钮的标记
为了根据当前网站状态显示和隐藏按钮,我们可以将元素的“dark”或“light”类与“color-mode”HTML自定义属性定义的网站当前状态结合起来。

根据网站当前配色方案隐藏元素的规则
我们进展顺利🔥。HTML和CSS已经就绪,默认颜色模式也已显示,现在是时候连接JavaScript代码,让按钮具备交互功能了。代码分为三部分。
- 定义一个函数,用于在深色模式和浅色模式之间切换。
- 创建一个事件处理程序,监听太阳和月亮按钮的点击事件。
- 在DOM中选择这些按钮。
颜色模式切换代码的工作原理如下:当用户点击按钮时,该toggleColorMode函数会检查按钮是否包含类名“light--hidden”。如果包含,则将文档的 color-mode 属性设置为“light”,从而启用浅色模式;如果不包含,则启用深色模式。但这还不是全部。该函数还会将用户本地存储中的一个条目设置为用户的偏好设置。您可以通过浏览器开发者工具的“存储”或“应用程序”面板中的“本地存储”选项来查看此设置。由于本地存储几乎会永久保留,因此即使用户退出浏览器,其浅色或深色模式的偏好设置也会在下次访问时保留。

用于切换深色或浅色模式的 JS
尊重用户配色方案偏好
看看我们取得了多大的进步!我们定义了深色和浅色两种配色方案,用户可以在两者之间切换,我们的网站甚至会记住用户上次的偏好设置。
但是,用户偏好设置还可以在另一个层面上进行,即在操作系统本身中进行设置。您可以在 Windows、macOS 和 Android 系统中设置颜色偏好,只是支持程度有所不同。如果用户费心更改了此偏好设置,那么如果我们能在网站首次加载时自动根据该偏好设置渲染网站,那就太好了。
借助 CSS 媒体特性 ` prefers-color-scheme`(可通过 JS 和 CSS 访问),我们可以实现这一点。以下是代码的工作原理。如果用户已在操作系统层面设置了配色方案偏好,且在之前的访问中未在本网站设置过偏好,则我们应该遵循操作系统层面的偏好,并相应地以浅色或深色模式渲染网站。如果用户已设置网站层面的偏好,则我们应该遵循该网站层面的偏好,而不是操作系统层面的偏好。为确保此代码在页面渲染之前执行,请将其放在<head>页面的 `<head>` 标签内。

确保操作系统或网站的颜色模式偏好设置得到尊重。
演示🎉
剩下的就是亲眼见证它的实际效果了。演示的所有源代码也都已提供。

深色模式切换完全指南
您可能已经注意到,深色模式越来越受欢迎。本文将提供一份完整的指南,指导您如何在网站上添加深色模式。
开启黑暗面的最佳实践
最近,CSS-Tricks 的 Chris Coyier 向所有准备“撰写关于暗黑模式的博客文章”的人发起了挑战。他列出了需要涵盖的 10 个要点。
- 解释深色模式
- 提供演示
- 解释一下,深色模式本身就可以在操作系统层面实现。
- 展示 JavaScript 如何了解操作系统级别的选择
- 让用户对颜色偏好拥有最终决定权
- 构建一个主题切换器,包括一些注意事项
- 看看还有哪些人在开发深色模式切换功能
- 看看还有哪些人写过这篇文章。
- 讨论哪些内容受支持,哪些内容不受支持。
- 将无障碍设计作为首要考虑因素
在我的帖子“完整版…
关于支持的说明
CSS 自定义属性
CSS 自定义属性或变量在 94.68% 的浏览器中受支持。IE 及更早版本的浏览器不支持此功能。虽然可以轻松提供备用方案,但用户在不支持的浏览器中将无法切换颜色模式,系统会使用您设置的默认值。

为不支持的浏览器提供备用方案
使用 SASS Mixin 实现回退自动化
编写额外的备用方案很繁琐。你可以使用 SASS mixin 来自动化这个过程,它会自动为你编写备用方案。

用于提供回退支持的 SASS Mixin
偏好配色方案
prefers-color-scheme 媒体查询在 80.85% 的浏览器中受支持。不支持该媒体查询应该不会造成任何问题。
对于不支持此功能的浏览器,我们可以采取的一种策略是隐藏切换按钮。为此,我们会检查浏览器是否支持自定义属性。如果不支持,则隐藏切换按钮。您可以通过在 IE 浏览器中打开演示来测试此功能。演示默认会使用浅色主题并隐藏切换按钮,因为它们无法正常工作。更新后的代码如下,已转译为 ES2015 兼容版本。

JS 中针对不支持的浏览器的回退机制
好了,各位!欢迎提出建议。@theroyalfig
资源
文章来源:https://dev.to/royalfi/the-complete-guide-to-the-dark-mode-toggle-d0g