在 WordPress 块主题中管理 CSS 样式

Avatar of Ganesh Dahal
Ganesh Dahal 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

我们为 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 主题 的演变过程。迄今为止,有三个默认主题支持全站编辑

但不要急于将 style.css 中的 CSS 替换为 theme.json 中的 JSON 属性-值对。在考虑这样做之前,仍然需要在 theme.json 中支持一些 CSS 样式规则。剩余的重要问题目前正在讨论中,旨在将所有 CSS 样式规则完全迁移到 theme.json 中,并将不同的 theme.json 源合并到一个 用于直接在 WordPress 站点编辑器 中设置全局样式的 UI 中。

全局样式 UI 集成到站点编辑器右侧面板中。(图片来源:学习 WordPress

这让我们处于一个相对艰难的境地。不仅 没有明确的覆盖主题样式的路径,而且不清楚这些样式的来源来自哪里——是来自不同层级的 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.jsonelements.link 对象上定义的样式。但这并不能完全概括元素的定义,因为某些元素也注册为块,例如标题和按钮块——但这些块仍然可以在其他块中使用。

以下是在 WordPress 6.1 之前,可在 theme.json 中设置样式的元素的表格,由 Carolina 提供

元素选择器支持位置
link<a>WordPress 核心
h1h6每个标题级别的 HTML 标签:<h1><h2><h3><h4><h5><h6>WordPress 核心
heading全局设置所有标题的样式,按各个 HTML 标签:<h1><h2><h3><h4><h5><h6>Gutenberg 插件
button.wp-element-button.wp-block-button__linkGutenberg 插件
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)。

Twenty Twenty-Three 主题中的每个按钮都共享相同的背景颜色,该颜色设置为 --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上设置了backgroundtext属性,使用了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 元素

全局样式

样式引擎


感谢您的阅读!我很乐意听到您自己对使用区块主题以及如何管理CSS的见解。