社区新闻

无需 theme.json 即可实现区块主题样式

查看官方原文 ↗ 发布于

如果你是老派的 WordPress 主题作者,或者对 CSS 非常熟悉,有时可能会觉得为区块主题添加样式受到限制。如果你试图坚持使用标准的 theme.json 系统,情况尤其如此。或者,也许你只是不喜欢使用 JSON 格式来处理设计。事实上,你可能有很多理由更愿意坚持使用久经考验的纯 CSS。

对于区块主题来说,完全可以选择不使用 JSON 而使用纯 CSS。根据项目的具体情况,这甚至可能是正确的路径。

在本文中,你将学习如何使用最新的技术,通过自定义 CSS 为区块主题添加样式。

你应该拥抱 theme.json

《精通 theme.json:你可能不需要 CSS》一文中,我详细阐述了你应该在 WordPress 中使用 theme.json 系统的所有理由。

老实说,我仍然 100% 支持那篇文章的内容。theme.json 是推荐的主题样式修改方式,随着时间的推移,它将变得更加强大,并越来越多地集成到编辑体验中。

需要注意的是,WordPress 的 theme.json 系统是一种标准化的方法,用于以 JSON 格式定义设置和样式,这种格式可以从 PHP 和 JavaScript 访问。这种标准有很多好处。例如,你可以自动集成到站点编辑器中的样式面板。这让你的主题用户可以通过用户界面查看和自定义这些样式。

我不会重复那篇文章中概述的所有优点。但我确实建议你阅读那篇文章,以全面了解其可能性。

对于本文,我将假设你完全理解 theme.json 的强大功能,但在你的使用场景中,使用它的好处并没有超过其缺点。也许你正在构建一个定制网站,客户永远不会与样式面板交互,也不需要以任何方式操作设计。你仍然可以利用许多区块编辑器的功能,同时编写自己的所有 CSS。

theme.json 的结构

在深入探讨如何不使用 JSON 处理区块主题样式之前,有必要分解一下你可以通过 theme.json 设置的各种项目,包括 JSON 模式、设置、样式等。

以下是可以在 theme.json 文件中定义的顶级属性:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"settings": {},
	"styles": {},
	"customTemplates": {},
	"templateParts": {},
	"patterns": []
}

本文仅关注选择不使用 styles 属性,该属性支持一个标准化的 CSS 子集。其他大多数项目几乎总是通过 JSON 定义才有意义,JSON 是设置和其他类型项目配置的理想格式。

组织你的样式表系统

在 WordPress 主题历史的大部分时间里,主题作者将大部分甚至全部 CSS 都放在主题的 style.css 文件中。在 Web 开发的早期,当大多数样式表与今天相比相对较小时,这种方法效果很好。最终,开发者创建了自己的包含样式表的系统。但 WordPress 设定的标准是全局(跨站点)加载一个样式表。

当区块编辑器以及后来的区块主题被引入时,WordPress 转向了一个标准:仅在前端实际需要为当前查看的页面加载 CSS。虽然这主要通过 theme.json 系统处理,但 WordPress 也包含了使用自定义样式表实现此功能的功能。

在本节中,让我们分解一下遵循 WordPress 仅在必要时包含 CSS 的标准,同时使用自定义样式表的最佳方法。

全局样式表

主题的 style.css 文件仍然是主题化的重要组成部分。你可以使用它来全局加载前端和编辑器的样式。

与过去不同,我不再建议将所有 CSS 都添加到 style.css 文件中。相反,仅将其用于应在前端和编辑器中全局可用的 CSS。特别是,不要将自定义区块样式放在里面,因为并非每个区块都在每个页面上加载。

要在前端加载主题的 style.css,请将此代码添加到主题的 functions.php 中:

add_action( 'wp_enqueue_scripts', 'themeslug_enqueue_styles' );

function themeslug_enqueue_styles() {
	wp_enqueue_style( 'themeslug-style', get_stylesheet_uri() );
}

要同时在编辑器中加载它,请添加此代码:

add_action( 'after_setup_theme', 'themeslug_add_editor_styles' );

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

有关 style.css 如何工作的更多信息,请查看主题手册中的主样式表文档。

区块样式表

区块样式表为区块样式提供了很大的灵活性,让你可以自由地为单个区块使用任何所需的 CSS。通常,这些会与区块样式变体的概念一起提及,但这并不是它们唯一的用例。你可以使用它们来简单地设置任何区块的默认设计样式。

假设你想为图像区块添加自定义样式。首先需要为此创建一个 CSS 文件。对于此示例,在主题中名为 /assets/blocks 的目录中创建一个 core-image.css 文件。

要仅在图像区块被使用时加载此文件,你必须使用 wp_enqueue_block_style() 函数,如以下代码所示:

add_action( 'init', 'themeslug_enqueue_block_styles' );

function themeslug_enqueue_block_styles() {
	wp_enqueue_block_style( 'core/image', array(
		'handle' => 'themeslug-block-core-image',
		'src'    => get_theme_file_uri( 'assets/blocks/core-image.css' ),
		'path'   => get_theme_file_path( 'assets/blocks/core-image.css' )
	) );
}

为区块添加样式时的一个最佳实践是在样式表中将选择器包装在 :root :where() 中。这将降低特异性,使其与大多数核心区块样式匹配,并允许用户通过管理后台的样式界面进行覆盖。

例如,如果你想为图像区块内的 <img> 元素添加 2px 的紫色边框,你的 core-image.css 文件中的代码将如下所示:

:root :where(.wp-block-image img) {
	border: 2px solid #a78bfa;
}

当你需要覆盖更具体的 CSS 规则时,使用 :root :where() 的做法有时可能不够,但对于大多数情况来说,这是一个很好的起点。

将 WordPress 和自定义 theme.json 预设与样式表结合使用

即使你不想在 JSON 中编写样式规则,而更喜欢使用样式表路径,你至少可以考虑使用预设。预设实际上只不过是 WordPress 生成的 CSS 自定义属性。它们还为用户提供了通过单个区块的检查器控件进行选择的选项。

以下是将基本调色板作为颜色预设提供的示例:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"settings": {
		"color": {
			"palette": [
				{
					"color": "#ffffff",
					"name": "Base",
					"slug": "base"
				},
				{
					"color": "#000000",
					"name": "Contrast",
					"slug": "contrast"
				},
				{
					"color": "#89cff0",
					"name": "Primary",
					"slug": "primary"
				}
			]
		}
	}
}

WordPress 会从这些预设自动生成 CSS 自定义属性,使它们可以在你的 theme.json 或你自己的样式表中全局使用:

:root {
	--wp--preset--color--base: #ffffff;
	--wp--preset--color--contrast: #000000;
	--wp--preset--color--primary: #89cff0;
}

假设你想将这些颜色分配给以下元素:

  • Base: 站点主体背景
  • Contrast: 站点文本颜色
  • Primary: 链接颜色

通常,你会使用 theme.json 中的 styles 部分来定义:

{
	"styles": {
		"color": {
			"background": "var(--wp--preset--color--base)",
			"text": "var(--wp--preset--color--contrast)"
		},
		"elements": {
			"link": {
				"color": {
					"text": "var(--wp--preset--color--primary)"
				}
			}
		}
	}
}

但没有规则说你必须这样做。同样,你可以完全跳过在 theme.json 中使用 styles

将其放入主题的 style.css 文件中将产生相同的效果:

body {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--primary);
}

并非二选一

虽然我主张尽可能多地使用 theme.json,但当核心功能不完全支持我的需求时,我也会使用自定义样式表。同时使用这两种方法是完全可以的。

如果你只是对 CSS 更熟悉,我理解坚持使用它的愿望。如果你更喜欢样式表,我也不会阻拦。

我也不会建议完全抛弃 theme.json,但在构建区块主题时,你绝对可以这样做。甚至可以从样式表开始,随着学习的深入,将更多内容集成到 theme.json 中。