我们为 WordPress 主题编写 CSS 的方式正经历着翻天覆地的变化。我最近分享了一种 在 WordPress 中添加流体排版支持 的技术,方法是使用 theme.json
,这是一个新的文件,WordPress 一直在努力推动,使其成为定义支持全站编辑 (FSE) 功能的 WordPress 主题样式的中心信息来源。
等等,没有 style.css
文件?我们仍然有它。事实上,style.css
仍然是块主题中必需的文件,尽管它的作用大大降低,仅用于注册主题的元信息。也就是说,事实上 theme.json
仍在积极开发中,这意味着我们正处于过渡期,您可能会发现样式定义在那里、在 styles.css
中甚至在块级别。
那么,在这些 WordPress FSE 时代,样式实际上是什么样的呢?这就是我想在这篇文章中介绍的内容。在 WordPress 主题开发者手册 中,关于块主题样式的文档缺乏,因此我们在这里介绍的所有内容都是我收集到的关于当前情况以及 WordPress 主题未来发展方向的讨论。
WordPress 样式的演变
WordPress 6.1 中包含的新开发功能使我们更接近于一个完全在 theme.json
中定义样式的系统,但在我们能够完全依靠它之前,还有很多工作要做。我们可以通过使用 Gutenberg 插件 来了解未来版本中会出现什么。这是实验性功能通常进行试运行的地方。
另一种了解我们所处位置的方法是查看 默认 WordPress 主题 的演变过程。迄今为止,有三个默认主题支持全站编辑
- Twenty Twenty-One (TT1):这是第一个与块兼容的默认主题的经典版本。还有一个块版本 (TT1 块),并且此后一直是块主题的首选资源。但是,TT1 中的所有 5900 行 CSS 都在
style.css
中。没有theme.json
文件。 TT1 块是我们第一次看到块编辑器时代中的样式,我们可以将其视为预告片而非模型。 - Twenty Twenty-Two (TT2):这是第一个真正的基于块的默认 WordPress 主题,也是我们第一次遇到
theme.json
的地方。该文件仅包含 373 行代码。其主要开发人员已做出协调努力,使其成为一个无 CSS 主题;但是,style.css
仍然附带了将近 150 行代码,因为并非所有theme.json
问题都已在发布前的实验性 Gutenberg 插件中得到解决。 - Twenty Twenty-Three (TT3):这是 WordPress 6.1 中附带的主题,也是第一个示例主题,在必需的
style.css
文件中没有任何 CSS。
但不要急于将 style.css
中的 CSS 替换为 theme.json
中的 JSON 属性-值对。在考虑这样做之前,仍然需要在 theme.json
中支持一些 CSS 样式规则。剩余的重要问题目前正在讨论中,旨在将所有 CSS 样式规则完全迁移到 theme.json
中,并将不同的 theme.json
源合并到一个 用于直接在 WordPress 站点编辑器 中设置全局样式的 UI 中。

这让我们处于一个相对艰难的境地。不仅 没有明确的覆盖主题样式的路径,而且不清楚这些样式的来源来自哪里——是来自不同层级的 theme.json
文件、style.css
、Gutenberg 插件还是其他地方?
theme.json
而不是 style.css
?
为什么使用 您可能想知道为什么 WordPress 正在转向基于 JSON 的样式定义而不是传统的 CSS 文件。来自 Gutenberg 开发团队的 Ben Dwyer eloquently 地阐述了为什么 theme.json
方法对主题开发者来说是一个优势。
值得阅读 Ben 的文章,但重点在于这段引用
覆盖 CSS(无论是布局、预设还是块样式)都对集成和互操作性构成障碍:前端和编辑器之间的视觉一致性变得难以维护,对块内部的升级可能会与覆盖冲突。此外,自定义 CSS 在其他块主题中的可移植性较差。
通过鼓励主题作者尽可能使用
theme.json
API,可以正确解决定义的样式“基础 > 主题 > 用户”的层次结构。
将 CSS 迁移到 JSON 的主要优势之一是 JSON 是一种机器可读格式,这意味着它可以通过获取 API 在 WordPress 站点编辑器 UI 中公开,从而允许用户修改默认值并自定义站点的外观,而无需编写任何 CSS。它还提供了一种一致地设置块样式的方法,同时提供了一个结构,该结构创建了特异性层,以便用户设置比 theme.json
中定义的设置具有更高的优先级。theme.json
中的主题级样式与全局样式 UI 中的用户定义样式之间的这种相互作用,使得 JSON 方法如此吸引人。
开发者在 JSON 中保持一致性,用户通过无代码自定义获得灵活性。这是一种双赢的局面。
当然还有其他好处,来自 WP Engine 的 Mike McAlister 在这条 Twitter 线程中列出了几个。您可以在 Make WordPress Core 博客上的 这篇深入讨论 中找到更多好处。阅读完之后,将 JSON 方法的优势与 在经典主题中定义和覆盖样式的可用方法 进行比较。
使用 JSON 元素定义样式
在 theme.json
能够设置主题哪些部分的样式方面,我们已经取得了很大进展。在 WordPress 6.1 之前,我们实际上只能设置标题和链接的样式。现在,使用 WordPress 6.1,我们可以将按钮、标题、引用和标题 添加到组合中。
我们通过定义 JSON 元素 来实现这一点。将元素视为存在于 WordPress 块中的单个组件。假设我们有一个包含标题、段落和按钮的块。这些单个部分是元素,并且在 theme.json
中有一个 elements
对象,我们在其中定义它们的样式
{
"version": 2,
"settings": {},
// etc.
"styles": {
// etc.
"elements": {
"button": { ... },
"h1": { ... },
"heading": { ... },
},
},
"templateParts": {}
}
描述 JSON 元素的更好方法是将其视为主题和块的低级组件,这些组件不需要块的复杂性。它们是 HTML 原语的表示形式,未在块中定义,但可以在块之间使用。它们在 WordPress(和 Gutenberg 插件)中的支持方式在 块编辑器手册 和 Carolina Nymark 编写的 全站编辑教程 中进行了描述。
例如,链接在 elements
对象中设置样式,但本身不是块。但是链接可以在块中使用,并且它将继承 theme.json
中 elements.link
对象上定义的样式。但这并不能完全概括元素的定义,因为某些元素也注册为块,例如标题和按钮块——但这些块仍然可以在其他块中使用。
以下是在 WordPress 6.1 之前,可在 theme.json
中设置样式的元素的表格,由 Carolina 提供
元素 | 选择器 | 支持位置 |
---|---|---|
link | <a> | WordPress 核心 |
h1 – h6 | 每个标题级别的 HTML 标签:<h1> 、<h2> 、<h3> 、<h4> 、<h5> 和 <h6> | WordPress 核心 |
heading | 全局设置所有标题的样式,按各个 HTML 标签:<h1> 、<h2> 、<h3> 、<h4> 、<h5> 和 <h6> | Gutenberg 插件 |
button | .wp-element-button.wp-block-button__link | Gutenberg 插件 |
caption | .wp-element-caption ,.wp-block-audio figcaption ,.wp-block-embed figcaption ,.wp-block-gallery figcaption ,.wp-block-image figcaption
,.wp-block-table 的 figcaption ,.wp-block-video 的 figcaption | Gutenberg 插件 |
cite 标签 | .wp-block-pullquote 中的 cite 标签 | Gutenberg 插件 |
如你所见,这还处于早期阶段,许多内容仍需要从 Gutenberg 插件迁移到 WordPress 核心。但你可以看到,例如,在主题中全局设置所有标题的样式将是多么快速,而无需在 CSS 文件或 DevTools 中搜索选择器。
此外,你还可以开始了解 theme.json
的结构如何形成某种特定性层级,从全局元素(例如 headings
)到单个元素(例如 h1
),以及块级样式(例如块中包含的 h1
)。
有关 JSON 元素的更多信息,请参见 WordPress 建议 和 Gutenberg 插件 GitHub 仓库中的 此开放工单。
JSON 和 CSS 特定性
让我们继续讨论 CSS 特定性。我之前提到过,JSON 样式方法建立了一个层次结构。这是真的。在 theme.json
中的 JSON 元素上定义的样式被视为默认主题样式。用户在全局样式 UI 中设置的任何内容都将覆盖默认值。
换句话说:**用户样式比默认主题样式具有更高的特定性**。让我们看一下按钮块,以了解其工作原理。
我正在使用 Emptytheme,这是一个没有任何 CSS 样式的空白 WordPress 主题。我将在新页面上添加一个按钮块。

好的,我们知道 WordPress 核心自带了一些简单的样式。现在,我将切换到 WordPress 6.1 中的默认 TT3 主题并激活它。如果我刷新包含按钮的页面,按钮的样式会发生变化。

您可以在 TT3 的 theme.json
文件中准确地看到 这些新样式的来源。这告诉我们,JSON 元素样式优先于 WordPress 核心样式。
现在,我将通过在子主题中覆盖它来修改 TT3,其中子主题包含一个 theme.json
文件,该文件将按钮块的默认背景颜色设置为红色。

但请注意上一个屏幕截图中的搜索按钮。它也应该是红色的,对吧?这意味着如果我所做的更改是在全局级别,那么它必须在另一个级别进行样式设置。如果我们想更改两个按钮,我们可以使用站点编辑器中的全局样式 UI 在用户级别进行更改。

我们使用全局样式 UI 将两个按钮的背景颜色都更改为蓝色,并修改了文本。请注意,那里的蓝色优先于主题样式!
样式引擎
这非常快速地概括了 WordPress 块主题中如何管理 CSS 特定性。但这并不是完整的情况,因为样式生成位置仍然不清楚。WordPress 有自己的默认样式,这些样式来自某个地方,它会使用 theme.json
中的数据获取更多样式规则,并使用全局样式中设置的任何内容覆盖这些规则。
这些样式是内联的吗?它们是否在单独的样式表中?也许它们是在 <script>
中注入到页面中的?
新的 样式引擎 有望解决这个问题。样式引擎是 WordPress 6.1 中的一个新 API,旨在使样式生成方式和样式应用位置保持一致。换句话说,它获取所有可能的样式源,并单独负责正确生成块样式。我知道,我知道。仅仅为了编写一些样式,就在其他抽象之上又添加了一个抽象。但是,鉴于样式可以来自许多地方,因此拥有一个集中的样式 API 可能是最优雅的解决方案。
我们只是对样式引擎进行了初步了解。事实上,根据 工单,到目前为止已完成以下工作。
- 审核和整合后端代码生成块支持 CSS 的位置,以便它们从同一位置(而不是多个位置)传递。这包括边距、填充、排版、颜色和边框等 CSS 规则。
- 删除重复的特定于布局的样式并生成语义类名。
- 减少为块、布局和元素支持打印到页面的内联样式标签的数量。
基本上,这是建立单个 API 的基础,该 API 包含主题的所有 CSS 样式规则,无论它们来自何处。它清理了 WordPress 在 6.1 之前注入内联样式的方式,并建立了语义类名系统。
有关样式引擎的长期和短期目标的更多详细信息,请参阅此 WordPress 核心讨论。您还可以关注 跟踪工单 和 项目看板 以获取更多更新。
使用 JSON 元素
我们稍微讨论了一下 theme.json
文件中的 JSON 元素,以及它们基本上是如何定义标题、按钮和链接等内容的默认样式的 HTML 基本元素。现在,让我们看看如何实际使用 JSON 元素以及它在各种样式上下文中的行为。
JSON 元素通常有两种上下文:**全局级别**和**块级别**。全局级别样式的定义比块级别样式的定义具有更低的特定性,以确保无论在何处使用块,块特定样式都具有优先级,以保持一致性。
JSON 元素的全局样式
让我们看一下新的默认 TT3 主题,并检查其按钮的样式设置方式。以下是 TT3 theme.json
文件的简化复制粘贴版本(完整代码),显示了全局样式部分,但您可以在此处找到原始代码。
查看代码
{
"version": 2,
"settings": {},
// ...
"styles": {
// ...
"elements": {
"button": {
"border": {
"radius": "0"
},
"color": {
"background": "var(--wp--preset--color--primary)",
"text": "var(--wp--preset--color--contrast)"
},
":hover": {
"color": {
"background": "var(--wp--preset--color--contrast)",
"text": "var(--wp--preset--color--base)"
}
},
":focus": {
"color": {
"background": "var(--wp--preset--color--contrast)",
"text": "var(--wp--preset--color--base)"
}
},
":active": {
"color": {
"background": "var(--wp--preset--color--secondary)",
"text": "var(--wp--preset--color--base)"
}
}
},
"h1": {
"typography": { }
},
// ...
"heading": {
"typography": {
"fontWeight": "400",
"lineHeight": "1.4"
}
},
"link": {
"color": {
"text": "var(--wp--preset--color--contrast)"
},
":hover": {
"typography": {
"textDecoration": "none"
}
},
":focus": {
"typography": {
"textDecoration": "underline dashed"
}
},
":active": {
"color": {
"text": "var(--wp--preset--color--secondary)"
},
"typography": {
"textDecoration": "none"
}
},
"typography": {
"textDecoration": "underline"
}
}
},
// ...
},
"templateParts": {}
}
所有按钮都设置了全局样式 (styles.elements.button
)。

--wp--preset--color--primary
CSS 变量,或 #B4FD55
。我们也可以在 DevTools 中确认这一点。请注意,名为 .wp-element-button
的类是选择器。相同的类也用于设置交互式状态的样式。

同样,所有这些样式设置都在全局级别进行,来自 theme.json
。每当我们使用按钮时,它都将具有相同的背景,因为它们共享相同的选择器,并且没有其他样式规则覆盖它。
顺便说一句,WordPress 6.1 添加了对 设置某些元素(如按钮和链接)的交互式状态样式 的支持,方法是在 theme.json
中使用伪类(包括 :hover
、:focus
和 :active
)或全局样式 UI。Automattic 工程师 Dave Smith 演示 此功能 在一个 YouTube 视频中。
我们可以通过 theme.json
(最好在子主题中,因为我们使用的是默认的 WordPress 主题)或站点编辑器中的全局样式设置(不需要子主题,因为它不需要代码更改)来覆盖按钮的背景颜色。
但这样所有按钮都会同时更改。如果我们想在按钮是某个特定块的一部分时覆盖背景颜色该怎么办?这就是块级样式发挥作用的地方。
元素的块级样式
要了解如何在块级别使用和自定义样式,让我们更改包含在搜索块中的按钮的背景颜色。请记住,有一个按钮块,但我们正在做的是在搜索块的块级别覆盖背景颜色。这样,我们就只在该处应用新颜色,而不是全局应用于所有按钮。
为此,我们在 theme.json
中的 styles.blocks
对象上定义样式。没错,如果我们在 styles.elements
上定义所有按钮的全局样式,我们可以在 styles.block
上定义按钮元素的块特定样式,它遵循类似的结构。
{
"version": 2,
// ...
"styles": {
// Global-level syles
"elements": { },
// Block-level styles
"blocks": {
"core/search": {
"elements": {
"button": {
"color": {
"background": "var(--wp--preset--color--quaternary)",
"text": "var(--wp--preset--color--base)"
}
}
},
// ...
}
}
}
}
看到那个了吗?我在styles.blocks.core/search.elements.button
上设置了background
和text
属性,使用了WordPress中预设的两个CSS变量。
结果如何?搜索按钮现在是红色的(--wp--preset--color--quaternary
),而默认的按钮区块保留了其亮绿色的背景。

我们也可以在开发者工具中看到这个变化。

如果我们想要为包含在其他区块中的按钮设置样式,也是同样的道理。而按钮仅仅是一个例子,所以让我们再来看另一个。
示例:为每个级别的标题设置样式
让我们用一个例子来巩固所有这些信息。这次,我们将
- 全局设置所有标题的样式
- 设置所有二级标题元素的样式
- 设置查询循环区块中二级标题元素的样式
首先,让我们从theme.json
的基本结构开始
{
"version": 2,
"styles": {
// Global-level syles
"elements": { },
// Block-level styles
"blocks": { }
}
}
这为我们的全局和区块级样式建立了框架。
全局设置所有标题的样式
让我们将headings
对象添加到我们的全局样式中并应用一些样式
{
"version": 2,
"styles": {
// Global-level syles
"elements": {
"heading": {
"color": "var(--wp--preset--color--base)"
},
},
// Block-level styles
"blocks": { }
}
}
这将所有标题的颜色设置为WordPress中预设的基本颜色。让我们也更改全局级别上二级标题元素的颜色和字体大小
{
"version": 2,
"styles": {
// Global-level syles
"elements": {
"heading": {
"color": "var(--wp--preset--color--base)"
},
"h2": {
"color": "var(--wp--preset--color--primary)",
"typography": {
"fontSize": "clamp(2.625rem, calc(2.625rem + ((1vw - 0.48rem) * 8.4135)), 3.25rem)"
}
}
},
// Block-level styles
"blocks": { }
}
}
现在,所有二级标题元素都设置为主要预设颜色,并具有流体字体大小。但也许我们希望在查询循环区块中使用二级标题元素时,它具有固定的fontSize
{
"version": 2,
"styles": {
// Global-level syles
"elements": {
"heading": {
"color": "var(--wp--preset--color--base)"
},
"h2": {
"color": "var(--wp--preset--color--primary)",
"typography": {
"fontSize": "clamp(2.625rem, calc(2.625rem + ((1vw - 0.48rem) * 8.4135)), 3.25rem)"
}
}
},
// Block-level styles
"blocks": {
"core/query": {
"elements": {
"h2": {
"typography": {
"fontSize": 3.25rem
}
}
}
}
}
}
}
现在我们为二级标题元素设置了三个级别的样式:所有标题、所有二级标题元素,以及在查询循环区块中使用的二级标题元素。
现有主题示例
虽然我们在本文中只查看了按钮和标题的样式示例,但WordPress 6.1支持为其他元素设置样式。在“使用JSON元素定义样式”部分有一个表格概述了它们。
您可能想知道哪些JSON元素支持哪些CSS属性,更不用说您将如何声明它们了。在等待官方文档的同时,我们最好的资源将是现有主题的theme.json
文件。我将根据它们自定义的元素提供主题链接,并指出自定义了哪些属性。
主题 | 自定义内容 | Theme JSON |
---|---|---|
Blockbase | 按钮、标题、链接、核心区块 | 源代码 |
Block Canvas | 按钮、标题、链接、核心区块 | 源代码 |
Disco | 按钮、标题、核心区块 | 源代码 |
Frost | 按钮、标题、链接、图注、引用、核心区块 | 源代码 |
Pixl | 按钮、标题、链接、核心区块 | 源代码 |
Rainfall | 按钮、标题、链接、核心区块 | 源代码 |
Twenty Twenty-Three | 按钮、标题、链接、核心区块 | 源代码 |
Vivre | 按钮、标题、链接、核心区块 | 源代码 |
请务必仔细查看每个theme.json
文件,因为这些主题包含了styles.blocks
对象上区块级样式的优秀示例。
总结
全站编辑器频繁的更改正变得越来越令人恼火,包括精通Gutenberg的用户。即使是非常简单的CSS规则,在经典主题中运行良好,由于我们之前讨论过的新的特异性层级,在区块主题中似乎也不起作用。
关于GitHub上重新设计站点编辑器为新浏览器模式的提议,Sara Gooding在WP Tavern的一篇文章中写道
除非您日夜都在使用该工具,否则很容易在尝试浏览站点编辑器时迷路。导航不流畅且令人困惑,尤其是在从模板浏览到模板编辑再到修改单个区块时。
即使作为Gutenberg区块编辑器和区块主题领域的早期积极使用者,我也有很多自己的挫败感。不过,我仍然乐观,并预计站点编辑器一旦完成,将成为用户和精通技术的主题开发者的一款革命性工具。这个充满希望的推文已经证实了这一点。与此同时,看来我们应该为更多变化做好准备,甚至可能是一段颠簸的旅程。
参考文献
我列出了我在研究本文信息时使用过的所有资源。
JSON 元素
- 元素 API(Gutenberg GitHub 仓库)
- Theme.json 元素(全站编辑)
- 元素样式(区块编辑器手册)
全局样式
- 全局样式路线图(Gutenberg GitHub 问题)
- 全局样式:元素支持跟踪(Gutenberg GitHub 问题)
样式引擎
- 区块编辑器样式:计划和目标(Make WordPress 博客)
- 区块样式生成(样式引擎)(Make WordPress 博客)
- 核心样式和主题自定义:后续步骤(Make WordPress 博客)
感谢您的阅读!我很乐意听到您自己对使用区块主题以及如何管理CSS的见解。
您好,Ganesh,我承认,现在我的头脑比回复Geoff的帖子“不确定如何使用WordPress”时更加清晰了。
我并不是说我突然变成了WP 6.1/FSE的粉丝,但我认为我的沮丧情绪已经停止恶化了 :-),我现在可以坐下来喝杯茶,展望未来,在那里我可能会被说服,这场巨变对主题开发者来说是一件好事。
再次感谢!
非常感谢。我很高兴它对您有所帮助。您如此优雅的话语,让我的一天都变得美好!
您好,Ganesh
非常感谢您的文章。这是我读过的关于这个主题最好和最完整的文章。这种新的API方法为设计师打开了许多新的视角。
干杯
Grégoire,非常感谢您的赞美之词。我很高兴它对您有所帮助。
您好。感谢您的文章!!!我有一个问题,每个区块中配置的“附加 CSS 类”如何处理?在区块主题中在哪里可以放置这些附加 CSS 类的样式?我应该何时添加附加类?
您好!这个链接资源解释了如何在区块中添加“附加 CSS 类”。希望这会有帮助。
非常感谢这篇非常有趣的文章!
如果我使用了 TT3 子主题,更改整个网站的字体族的解决方案是什么?theme.json?
再次感谢。
这是一篇非常好的文章,谢谢。
不幸的是,我认为这对于一个实际上很少发生的用例进行了过度优化,“如果我需要在一个站点上迭代 10 个主题和开发人员会怎样”……因此,我总体上对 WP 生态系统的信任度因此降低了,因为“框架膨胀”现在不仅扩展到主题框架,还扩展到 WP 核心本身,我只能希望像 Underscores 这样的空白框架仍然是一种解决方法。
感谢您的信息以及指向 WordPress CSS 手册的链接