无需 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 中。