WebKit 中的深色模式支持

随着去年 macOS Mojave 中深色模式的引入,Web 开发人员一直在寻求 Safari 中的支持,以样式化与系统外观匹配的 Web 内容。随着 macOS 10.14.4、iOS 13 和 iPad OS 13 中 Safari 12.1 更新的发布,WebKit 和 Safari 中对深色模式的支持也随之而来。

WebKit.org Getting Started page shown in light modeWebKit.org Getting Started page shown in dark mode

深色模式行为

默认情况下,当用户处于深色模式时,页面的外观行为没有变化。这保留了 Web 设计师近三十年来一直持有的标准假设——即页面默认采用白色背景和黑色文本。在深色模式下改变这些默认设置将是一个 Web 兼容性噩梦。

然而,这使得深色模式下屏幕的很大一部分区域可能显示亮色内容。对于简单内容,应用程序可以为深色模式转换文档中的颜色。macOS Mojave 中的邮件应用程序就是这样做的——它以深色模式的解释显示简单的电子邮件消息。

并非所有 Web 内容都是简单的。因此,Safari 和 WebKit 不会自动将 Web 内容变暗——文档需要选择启用深色模式。指示您的内容支持深色模式的主要方法是采用新的 color-scheme 样式属性,该属性在此提案中指定。

您可以在样式表中这样使用此继承属性

:root {
    color-scheme: light dark;
}

在根元素上指定 lightdark 值可以让引擎知道文档支持这两种模式。这会将页面的默认文本和背景颜色更改为与当前系统外观匹配。此外,标准表单控件、滚动条和其他命名的系统颜色会自动改变其外观。如果没有此声明,引擎使用深色表单控件或深色配色方案是不安全的,因为许多文档都是基于假设的浅色配色方案设计的。

例如,这个简单的页面,如果指定了 color-scheme: light dark,将完全准备好在两种外观下使用。

Example page in light modeExample page in dark mode

当使用高对比度辅助功能模式或不同的浏览器和系统版本时,这些默认的背景和文本颜色可以有不同的值。您不应假设它们将始终是相同的颜色值。

color-scheme 样式属性也支持选择文档中特定元素的样式规则,而不仅仅是根元素。如果您有需要特定配色方案的内容或组件(特别是带有表单控件的内容),这将非常有用,因为深色模式下的表单控件在浅色背景上看起来不正确。

此样式属性还允许邮件应用程序知道电子邮件消息应使用哪种配色方案,因为它会影响应用于消息颜色的自动变暗转换。在富文本电子邮件消息中声明 color-scheme: light dark 可让邮件应用程序知道它支持自己的深色模式样式。您还可以指定 light only,通知邮件应用程序不应转换您的浅色配色方案电子邮件消息。

如果使用元标签声明更适合您的内容,还有 <meta name="color-scheme">,此提案中指定了它。

color-scheme 属性和元标签在 Safari 技术预览版 81 和 macOS Catalina 中从 supported-color-schemes 重命名而来。旧名称在 macOS 10.14.4 中受 WebKit、Safari 和邮件应用程序支持。这是一个正在开发中的标准,未来可能会发生变化。

深色模式样式化

定义 color-scheme 可以让您开始处理简单内容。对于大多数 Web 内容,您需要采用此提案中指定的 prefers-color-scheme 媒体查询,以使用自定义颜色或图像来样式化元素。您可以在任何支持媒体查询的地方使用此媒体查询,例如在 <picture> 元素中或通过 window.matchMedia() 进行脚本触发。

在文档中部署深色和浅色配色方案的最佳方法是利用 CSS 变量。然后,您可以通过媒体查询轻松地在一个地方指定颜色,并在整个样式表中使用这些变量。当媒体查询匹配时,无论变量在何处使用,它们都会随任何外观变化而自动切换。

这是一个使用媒体查询通过 CSS 变量指定颜色值的示例

:root {
    color-scheme: light dark;
    --special-text-color: hsla(60, 100%, 50%, 0.5);
    --border-color: black;
}

@media (prefers-color-scheme: dark) {
    :root {
        --special-text-color: hsla(60, 50%, 70%, 0.75);
        --border-color: white;
    }
}

.special {
    color: var(--special-text-color);
    border: 1px solid var(--border-color);
}

图像和深色模式

对于大多数主视觉图像,它们在深色模式下仍然会看起来很棒——它们甚至可能比以往任何时候都更突出!如前所述,您可以在 <picture> 元素或样式规则中使用 prefers-color-schemes 媒体查询来选择不同的图像(如果您有深色模式版本)。

对于我们的简单示例页面,我们可以选择一张不同的莫哈维沙漠主视觉图像

<picture>
    <source srcset="mojave-night.jpg" media="(prefers-color-scheme: dark)">
    <img src="mojave-day.jpg">
</picture>
Example page in light modeExample page in dark mode

您可能还有一些用于控件或其他交互元素的图像,需要为深色模式进行更新。许多网站现在都为这些字形采用了矢量图像,例如 SVG 或 Web 字体。字体会自然地适应您的深色模式文本颜色,但 SVG 图像需要一些额外的样式才能看起来正确。使用 SVG 的一个技巧是使用 currentColor 关键字,让嵌入式 SVG 使用当前的文本颜色——从而自动适应您的深色模式文本颜色。您还可以使用 CSS 变量来样式化 SVG 内部的颜色,就像您的其他元素一样。

对于无法通过其他方式样式化的特定图像,您可以使用 CSS invert() 滤镜。如果图像也有颜色,您可能会考虑使用 invert() hue-rotate(180deg) 来适度保留图像意图。无论如何,您不应在大范围内容上使用整体滤镜,因为这可能会导致高内存和性能成本。直接样式化颜色是颜色准确性和性能的最佳方法。

调试深色模式

Web Inspector 现在在“元素”选项卡中包含一个导航栏按钮,用于根据您当前的整体系统偏好来切换深色或浅色模式。这使您可以在两种外观下快速测试页面,而无需在系统偏好设置中切换整个系统外观。“样式”侧边栏会更新以反映当前匹配的规则以及任何 CSS 颜色变量。

Dark Mode Web Inspector Toggle

示例

您可能已经注意到,如果您在 macOS 10.14.4 上使用 Safari,WebKit.org 网站已经支持深色模式。由于我们很久以前就在 Safari 技术预览版中添加了支持,许多其他网站也采用了深色模式。以下是一些您今天可以查看的示例

  • Twitter — 社交网络服务。
  • Emojipedia — 表情符号含义之家。
  • NSHipster — 一本关于 Objective-C、Swift 和 Cocoa 中被忽视部分的期刊。
  • CSS DB — 一个分阶段 CSS 功能的数据库。
  • Stuff & Nonsense — 一家设计工作室,专门为数字产品和网络提供创意设计。

附加信息

请务必观看我们的 WWDC 19 视频 在您的 Web 内容中支持深色模式,了解在 iOS 13 和 macOS Catalina 中添加深色模式支持的技术。