社区新闻

精通区块主题的明暗模式样式设计

查看官方原文 ↗ 发布于

我一直想解决的一个挑战是创建同时支持明暗模式的主题。多年来,开发者们使用了多种方法来实现这一点,有些方法比其他方法更复杂。但在着手应对这个挑战时,我为自己设定了一些基本规则:

  • 解决方案必须尊重网站访问者的操作系统偏好。
  • 主题用户无需采取任何额外步骤即可使其工作。
  • 代码必须尽可能放在 theme.json 中(需要少量额外的 CSS)。

基本上,我想以最省力的方式实现暗模式。我还希望在使用现代 CSS 功能的同时,尊重 WordPress 的全局样式引擎。

在本教程中,我将详细介绍我提出的解决方案,这个方案在过去几个月里被广泛使用。虽然存在一些限制,但我相信这是最具前瞻性的解决方案。

设置

在本教程中,我选择以 Twenty Twenty-Four 主题为基础创建一个子主题,并使用父主题的默认配色方案。你可以在这些截图中看到结果:

Twenty Twenty-Four 在明模式下查看。 Twenty Twenty-Four 在暗模式下查看。

要跟着操作,请创建一个名为 tt4-dark-mode 的新子主题,并在其中包含以下文件:

  • style.css
  • functions.php
  • theme.json
  • /assets/editor.css

像往常一样,在激活主题之前,将基本的文件头设置添加到你的 style.css 文件中:

/*!
 * Theme Name:        TT4: Dark Mode
 * Description:       Exploring dark mode with Twenty Twenty-Four.
 * Version:           1.0.0
 * Tags:              block-patterns, block-styles, editor-style, full-site-editing, wide-blocks
 * Template:          twentytwentyfour
 * Text Domain:       tt4-dark-mode
 * Tested up to:      6.7
 * Requires at least: 6.6
 */

使用现代 CSS 功能

在本教程中,你将使用两个目前尚未获得 100% 浏览器支持但已被广泛使用的 CSS 功能:

  • color-scheme CSS 属性,用于定义元素可以安全呈现的配色方案。该属性拥有超过 95% 的浏览器支持率,因此使用起来相对安全。
  • light-dark() 用于定义明暗两种颜色的 CSS 颜色函数。输出颜色基于用户的操作系统偏好。它旨在与 color-scheme 属性结合使用。目前拥有超过 86% 的浏览器支持率,如果支持现代浏览器,可以安全使用。

color-scheme 属性和 light-dark() 函数是本教程所用方法的基础。它们都是 2024 年的基线 CSS 标准,因此挑战在于让它们与 WordPress 标准协同工作。

启用明/暗模式配色方案

为了让浏览器能够根据用户偏好自动切换到明模式或暗模式,你必须设置 color-scheme 属性。虽然可以在单个元素上设置此属性,但你应该针对整个页面的 :rootcolor-scheme 支持多个值,但 light dark 是告诉浏览器确定使用哪种方案进行明暗切换的值。

目前没有通过 theme.json 设置此属性的标准,但你可以使用 styles.css 字段来定义自定义 CSS:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"styles": {
		"css": ":root { color-scheme: light dark; }"
	}
}

需要注意的一个潜在问题是,styles.css 属性可能会在样式变体或子主题的 theme.json 中被意外覆盖。父 theme.json 中的值不会被合并。如果这对你的项目可能是个问题,可以尝试另一种解决方案:

替代方法:使用样式表

我更喜欢上面的 theme.json 方法,因为它不需要任何额外的代码。但如果你希望或需要通过样式表设置配色方案,可以将此 CSS 添加到你的 style.css 文件中:

:root {
	color-scheme: light dark;
}

当然,你需要确保 style.css 同时包含在前端和编辑器中。通过将此代码片段添加到你的 functions.php 文件中来实现:

add_action( 'wp_enqueue_scripts', 'tt4_dark_mode_enqueue_assets' );

function tt4_dark_mode_enqueue_assets() {
	wp_enqueue_style( 'tt4-dark-mode', get_stylesheet_uri() );
}

add_action( 'after_setup_theme', 'tt4_dark_mode_theme_setup' );

function tt4_dark_mode_theme_setup() {
	add_editor_style( get_stylesheet_uri() );
}

使用 CSS 标准设计两种颜色

至此,你已经完成了基本设置。构建明暗配色方案的难点不在于代码本身,而在于设计——即选择正确的颜色。这更像是一门艺术,而不是简单地翻转颜色,那样效果不会好。这超出了本教程的范围。

我假设你已经为自己的项目定义了完整的明暗配色方案。在本教程中,我已经完成了为 Twenty Twenty-Four 现有的默认明色调色板创建暗色方案的工作。

重要的是如何在 theme.json 中定义这些颜色。还记得前面提到的 light-dark() CSS 函数吗?你将使用它为调色板中定义的每种颜色定义明暗两种值。

以下是白色 (#ffffff) 和黑色 (#000000) 与 light-dark() 一起使用时的示例:

light-dark( #ffffff, #000000 );

这告诉浏览器,当用户偏好明色方案时使用 #ffffff,偏好暗色方案时使用 #000000。任何 CSS 颜色值在这里都有效,因此具体值实际上取决于你的主题设计。

现在打开你一直在使用的 theme.json 文件,添加一个新的 settings.color.palette 部分并定义这些颜色。你完整的 theme.json 文件现在应该如下所示:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"settings": {
		"color": {
			"palette": [
				{
					"color": "light-dark(#f9f9f9, #1c1c1c)",
					"name": "Base",
					"slug": "base"
				},
				{
					"color": "light-dark(#ffffff, #111111)",
					"name": "Base / Two",
					"slug": "base-2"
				},
				{
					"color": "light-dark(#111111, #ffffff)",
					"name": "Contrast",
					"slug": "contrast"
				},
				{
					"color": "light-dark(#636363, #888888)",
					"name": "Contrast / Two",
					"slug": "contrast-2"
				},
				{
					"color": "light-dark(#A4A4A4, #3d3d3d)",
					"name": "Contrast / Three",
					"slug": "contrast-3"
				},
				{
					"color": "light-dark(#cfcabe, #60544c)",
					"name": "Accent",
					"slug": "accent"
				},
				{
					"color": "light-dark(#c2a990, #9d7359)",
					"name": "Accent / Two",
					"slug": "accent-2"
				},
				{
					"color": "#d8613c",
					"name": "Accent / Three",
					"slug": "accent-3"
				},
				{
					"color": "light-dark(#b1c5a4, #465a3b)",
					"name": "Accent / Four",
					"slug": "accent-4"
				},
				{
					"color": "light-dark(#b5bdbc, #4d5757)",
					"name": "Accent / Five",
					"slug": "accent-5"
				}
			]
		}
	},
	"styles": {
		"css": ":root { color-scheme: light dark; }"
	}
}

如你所见,几乎所有的颜色定义都包含了明暗两种十六进制颜色代码。我没有设置其中一个颜色 (accent-three),因为它在明暗模式下都表现良好。这算是一个意外的惊喜,但它说明了如何定义颜色是特定于你的设计的。

要测试,请在计算机的显示模式之间切换明暗(根据你的操作系统会有不同的设置)。

编辑器小修复

到目前为止,你学到的实现在编辑器画布和前端都能工作。但在暗模式下,编辑器 UI 中的各种颜色指示器并未反映暗色。要解决此问题,你需要使用与之前相同的 color-scheme 定义添加几行 CSS。

在你的主题中创建一个名为 /assets/editor.css 的新文件,并在其中添加此 CSS:

.component-color-indicator,
.block-editor-color-gradient-control,
.components-circular-option-picker__option {
	color-scheme: light dark;
}

这告诉 UI 中的各种颜色指示器和控件使用首选的明或暗方案。

现在在编辑器中加载这个样式表:

add_action( 'enqueue_block_editor_assets', 'tt4_dark_mode_editor_assets' );

function tt4_dark_mode_editor_assets() {
	wp_enqueue_style(
		'tt4-dark-mode-editor',
		get_theme_file_uri( 'assets/editor.css' )
	);
}

此方法的当前限制

使用 light-dark() 的一个主要缺点是,用户可以通过站点编辑器中的样式面板覆盖你主题定义的调色板中的单个颜色:

站点编辑器屏幕中的 WordPress 样式编辑器。显示的主题为暗色,样式面板已打开到颜色选项卡以编辑颜色。

这很成问题,因为 WordPress 目前没有基于 UI 的方法来同时定义明暗两种十六进制代码。当用户覆盖单个颜色时,无论模式如何,都将使用他们的自定义颜色。

对于分发的主题或客户有权编辑样式的网站,我还没有找到解决方案。我最初的想法是禁用此功能,但 WordPress 目前不支持此功能。

尽管存在这个限制,这仍然是一条值得进一步探索的途径。color-schemelight-dark() 已经是 CSS 标准的一部分,因此 WordPress 在未来将其正式采纳为 UI 的一部分是合理的。

甚至可以制作一个按钮来切换明暗模式,但让我们留到另一天的教程中。我希望在此期间能看到你的成果。