定义全局样式

Avatar of Ganesh Dahal
Ganesh Dahal

让我们进入主题的另一个顶级部分:theme.json,在这里我们可以配置块主题的 CSS:样式。我们将了解它的确切含义,以及如何使用它来覆盖和应用我们在第 2 部分中介绍的预设设置值。

由 DigitalOcean 提供

DigitalOcean 提供您在任何阶段支持业务增长的云计算服务。 立即获取 200 美元的免费积分!

在本系列的第 2 部分中,我们介绍了在 theme.json 文件中启用 WordPress 块主题中某些功能的过程。我们在文件的 settings 部分花费了时间,概述了各种可用功能以及它们如何允许我们使用预设值自定义 WordPress 站点编辑器中的全局样式 UI,这些预设值映射到作用域为 <body> 元素的 CSS 自定义属性值。

目录


样式部分 (styles)

styles 部分与我们在上一篇文章中介绍的 settings 部分并列,是顶级部分。

{
  "version": 2,
  "settings": {},
  "styles": {
    // etc.
  }
}

我们在第 2 部分了解到,settings 部分定义了顶级元素的默认样式 - 通常应用于 <body> 元素的 CSS。styles 部分是我们可以使用更细粒度的样式来覆盖这些预设的地方,这些样式应用于特定全局元素(例如 <h1>)和特定块(例如 theme.json 文件 来自 Twenty Twenty-Three,以及来自 主题目录 的其他最新块主题)。

换句话说,settings 是“顶级”样式,它们会级联到所有元素。我们可以在 styles 部分覆盖这些预设,在其中将样式应用于特定的 elementsblocks。事实上,elementsblocksstyles 的子部分。

{
  "version": 2,
  "settings": {},
  "styles": {
    // Global element styles
    "elements": {},
    // Block styles
    "blocks": {}
  }
}

很棒的一点是,theme.json 的布局方式类似于 CSS 样式表,可以使样式级联。如果 settings 用于配置全局样式功能,那么 styles 是我们在处理特定全局 elements 和单个 blocks 时覆盖这些预设的地方。

支持的属性

当我们在第 2 部分查看 settings 部分时,我们看到它包含可以在块主题中启用和配置的“功能”。关于 styles 部分,我们正在定义 CSS 属性。

事实上,styles 部分中包含的对象映射到实际的 CSS 属性。例如,styles.border-color 对应于 CSS 中的 border-color 属性。

因此,在我们深入 styles 部分以及如何自定义块主题的外观之前,我们应该确切地了解我们正在使用的 CSS。下表概述了截至 WordPress 6.1 时,在 styles 部分中当前支持的所有 CSS 属性。

属性完整表
属性样式CSS 等效项其他属性
bordercolorborder-color
radiusborder-radius
styleborder-style
widthborder-width
topborder-topcolorstylewidth
rightborder-rightcolorstylewidth
bottomborder-bottomcolorstylewidth
leftbottom-leftcolorstylewidth
colorbackgroundbackground-color
gradientbackground-image
textcolor
spacingblockGapgap(在 Flexbox 和 Grid 容器中)
marginmarginbottom, leftrighttop
paddingpaddingbottomleftrighttop
typographyfontFamilyfont-family
fontSizefont-size
fontStylefont-style
fontWeightfont-weight
letterSpacingletter-spacing
lineHeightline-height
textDecorationtext-decoration
textTransformtext-transform
filterduotonefilter
shadowbox-shadow
outlinecoloroutline-color
offsetoutline-offset
styleoutline-style
widthoutline-width

在设置这些属性时,有一些需要注意的地方。

  • 没有 逻辑属性 等效项。例如,支持 margin-left,但截至目前,margin-inline-start 还不支持。
  • 支持多种颜色格式,例如 rgbahsla,但不支持 新的语法,例如 rgb(255, 255, 255 / .5)

顶级样式

我们在第 2 部分已经介绍了顶级样式。“顶级”是指应用于根元素 (<html>) 以及 <body> 的全局样式。这些样式在某种程度上是“顶级”的,因为默认情况下它们会继承到主题中的所有内容。

CSS 中的经典示例是在 <body> 元素上设置默认字体大小。

body {
  font-size: 1.125rem;
}

现在,每个元素的 font-size 值都为 1.125rem,除非在其他地方被覆盖。您可能认为顶级样式是在 theme.jsonstyles 部分中设置的。但是,如果您还记得本系列中的上一篇文章,顶级样式是我们定义在 settings 部分中的预设值。

{
  "version": 2,
  "settings": {
    "typography": {
      "fontSizes": {
        "size": "1.125rem",
        "slug": "medium"
      }
    }
  },
  "styles": {}
}

在幕后,WordPress 样式引擎会生成一个 CSS 自定义属性,该属性可以应用于顶级元素的 <body>

body {
  font-size: var(--wp--preset--font-size--medium);
}

...这将产生与我们在 CSS 中预期的结果完全相同的结果。

body {
  font-size: 1.125rem;
}

现在,我们可以跳入 styles 部分,以在两个不同的级别覆盖这种顶级样式:elementsblocks

元素级样式

如果我们想将该顶级 font-size 作用域限定到特定元素呢?全局元素有点难以理解,因为它们既是块,又可以嵌套在其他块中。

elements 视为“核心”块。这实际上是 WordPress 手册中对它们的称呼,而且很好地描述了它们是什么:与 WordPress 核心捆绑在一起的块。

标题是核心块的一个完美示例。有一个 标题块,我们可以用它来将任何标题级别 (<h1><h6>) 添加到页面或帖子中。因此,如果您需要在页面上放置一个标题 2 元素,您有一个专门的块可以做到这一点。

但标题 2 可能是另一个块的一部分。例如,如果您要在页面上添加一个 查询循环块,您将获得一个帖子列表,每个帖子都包含一个 帖子标题块,该块会输出一个 <h2> 元素。

Query Loop block in the WordPress Block Editor with a Heading 2 element.

如果您想对所有标题元素进行样式设置,无论其级别如何,您可以在 theme.jsonelements 对象中进行操作。

{
  "version": 2,
  "settings": { }
  "styles": {
    // Global-level styles
    "elements": {
      "heading": { ... },
    }
  }
}

假设 CSS color 属性在 settings 中设置为黑色作为顶级样式。

{
  "version": 2,
  "settings": {
    // Top-level styles
    "color": {
      "palette": {
        "color": "#000000",
        "name": "Contrast",
        "slug": "contrast"
      }
    }
  },
}

WordPress 样式引擎 会创建一个 CSS 自定义属性,该属性可以应用于顶级元素的 <body>

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

也许您希望所有标题的颜色与应用于 <body> 元素的颜色不同。您可以在 styles.elements.heading 上设置该颜色,以使用深灰色来覆盖黑色。

{
  "version": 2,
  "settings": {
    // Top-level style presets
    "color": {
      "palette": {
        "color": "#000000",
        "name": "Contrast",
        "slug": "contrast"
      }
    }
  },
  "styles": {
    // Global-level styles
    "elements": {
      "heading": {
        "color": {
          "text": "#333333"
        }
      }
    }
  }
}

另一种方法是在 settings.color.palette 中配置一个新的颜色,并将生成的 CSS 自定义属性应用于 styles.elements.heading.color.text

好的,但也许您希望标题 2 全局元素比其他标题级别更突出。您可以使用分配给 h2 元素的另一个颜色值来覆盖所有核心标题元素的深灰色。

{
  "version": 2,
  "settings": {
    // Top-level style presets
    "color": {
      "palette": {
        "color": "#000000",
        "name": "Contrast",
        "slug": "contrast"
      }
    }
  },
  "styles": {
    // Global-level styles
    "elements": {
      "heading": {
        "color": {
          "text": "#333333"
        }
      },
      "h2": {
        "color": {
          "text": "#F8A100"
        }
      }
    }
  }
}

截至目前,以下全局元素当前在 styles.elements 部分中受支持。

JSON 属性生成的选取器用例
elements.buttons按钮按钮块,块
elements.heading标题标题块,
elements.h1elements.h6<h1><h6>网站标题、文章标题、区块
elements.link<a>链接
elements.citeblockquote.cite, quote.cite引用、长引用
elements.caption<figcaption>, <caption>图片、表格
elements.spacing.padding内边距标题、行、区块、段落
elements.typography排版标题、段落

块级样式

styles 中还有一个级别,用于自定义单个区块的 CSS

{
  "version": 2,
  "styles": {
    // Top-level styles
    // etc.

    // Global-level styles
    "elements": { },

    // Block-level styles
    "blocks": {  }
  }
}

让我们继续上一节的内容。我们在顶层的 styles 中将 color 属性设置为黑色,然后在 styles.elements.heading 中为所有标题覆盖了该颜色,然后在 styles.elements.h2 中仅为标题 2 元素覆盖了该颜色。以下是代码:

{
  "version": 2,
  "styles": {
    // Top-level styles
    "color": "#000000",

    // Global-level styles
    "elements": {
      "heading": {
        "color": {
          "text": "#333333"
        }
      },
      "h2": {
        "color": {
          "text": "#f8a100"
        }
      },
    }
  }
}

之前,我们讨论了像标题 2 这样的全局元素也可以是另一个区块的一部分。我们以“查询循环”区块为例,其中标题 2 用于每个文章标题。

到目前为止,“查询循环”区块的文章标题颜色将是 #F8A100,因为这是在 styles.elements.h2 中设置的。但是,如果要将“查询循环”区块的标题 2 元素设置为另一种颜色,而不影响其他标题,则可以在 styles.blocks 部分覆盖它。

{
  "version": 2,
  "styles": {
    // Top-level styles
    "color": "#000000",

    // Global-level styles
    "elements": {
      "heading": {
        "color": {
          "text": "#333333"
        }
      },
      "h2": {
        "color": {
          "text": "#F8A100"
        }
      }
    },
    "blocks": {
      "core/query": {
        "elements": {
          "h2": {
            "color": {
              "text": "var(--wp--preset--color--primary)"
            }
          }
        }
      }
    }
  }
}

在幕后,WordPress 样式引擎会为“查询循环”区块的 <h2> 元素创建 CSS

.wp-query h2 {
  color: var(--wp--preset--color--primary);
}

很棒吧?现在我们有了一种方法,可以以结构化的方式设置默认样式并在主题的各个级别覆盖这些样式,这与 CSS 级联 非常相似。

查看 WordPress 手册,了解 在区块编辑器中可用的所有区块的完整列表

交互式样式

如果要自定义不同交互状态的 CSS 怎么办?到目前为止,我们看到的所有内容都非常适合为核心区块(如按钮)设置样式,但是当有人将鼠标悬停在按钮区块上时,样式会怎样?或者当按钮处于焦点状态时?

我们可以使用 CSS 伪类 来实现。您可能已经很熟悉使用 :hover:focus:active:visited 等伪类。它们非常常见!

幸运的是,对使用伪类为某些核心区块(如按钮和链接)设置交互状态的支持 在 WordPress 6.1 中获得了 theme.json 支持。以下是一个从我之前的一篇文章中摘录的示例,它在鼠标悬停在主题的按钮元素上时添加了一个 box-shadow

{
  "version": 2,
  "settings": {},
  "styles": {
    "elements": {
      "button": {
        ":hover": {
          "shadow": "10px 10px 5px 0px rgba(0,0,0,0.66)"
        }
      }
    }
  }
}

WordPress 样式引擎会读取此代码并生成以下 CSS

.wp-button:hover {
  box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);
}

但在您急于创建所有交互式样式之前,请注意,截至 WordPress 6.1,theme.json 目前仅支持 :hover:focus:active 交互式伪类,即使是这些伪类也仅限于 buttonlink 元素。但正如 这篇文章 中所述,将来可能会扩展到其他元素,包括特定于表单元素的伪类。

因此,目前,以下是如何自定义按钮交互式样式的最完整方式的示例。

{
  "version": 2,
  "styles": {
    "elements": {
      "button": {
        "color": {
          "background": "#17A2b8",
          "text": "#ffffff"
        }
        ":hover": {
          "color": {
            "background": "#138496"
          }
        },
        ":focus": {
          "color": {
            "background": "#138496"
          }
        },
        ":active": {
          "color": {
            "background": "#138496"
          }
        }
      }
    }
  }
}

如果将 elements.button 更改为 elements.link,则可以使用相同的方法。

WordPress 手册中提到了另一个 JSON 对象,名为 css,但除了提到它用于设置其他 theme.json 属性未处理的自定义 CSS 之外,没有其他文档。

引用样式

theme.json 中还提供了一个 引用样式 功能。这使您可以使用 ref: 术语引用之前定义的根级别样式属性。

在前面的顶级样式示例中,我们在 styles 属性的根目录中使用 styles.color.background 属性注册了以下背景颜色。

"styles": {
  "color": {
    "background": "var(--wp--preset--color--base)"
  }
}

我们可以将同一个样式属性重复使用到任意数量的区块中

{
  "color": {
    "text": { ref: "styles.color.background" }
  }
}

全局样式变体

主题可以包含多个 theme.json 文件。为什么?因为这样可以创建 全局样式变体

该链接将带您进入全局样式变体的正式文档,但总体思路是这样的:theme.json 包含所有默认值,并位于主题文件夹的根目录中,其他 theme.json 文件将添加到主题文件夹中,这些文件是默认主题的“变体”。

工作原理如下:假设我们已经配置好了默认的 theme.json 文件,它位于主题的根目录中。现在假设您想要实现一个“暗黑模式”功能,允许用户在亮色和暗色调色板之间切换颜色。我们将创建一个新文件,例如 dark.json,并将其放在主题中名为 /styles 的新文件夹中。我们可以根据需要添加任意数量的这些文件,以创建您想要的各种变体。

theme-folder/
|__ /assets
|__ /patterns
|__ /templates
|__ /parts
|__ /styles
    |__ dark.json
|__ index.php
|__ functions.php
|__ style.css
|__ theme.json

默认的 theme.json 文件与我们的 dark.json 变体文件之间最大的区别是,我们的变体文件包含一个 title 字段,使我们可以将其与其他 JSON 文件区分开来。

{
  "version": 2,
  "title": "Dark",
  "styles": {}
}

一旦激活,我们在这里添加的任何内容都会覆盖 theme.json 中的内容。如何激活全局样式变体?您会在“网站编辑器”(仪表盘→外观→编辑器)的“浏览样式”(编辑器→样式→“浏览样式”)下找到它。这是默认的 Twenty Twenty-Three 主题提供的所有不同变体的秘诀。

The full-site template editing screen with the style variations panel open.

您可以在 这篇文章 中详细了解如何构建区块主题样式变体。

其他资源

总结

我们离完整了解 theme.json 文件已经很近了。我们已经介绍了它的结构、如何启用功能以及如何在主题、全局和区块级别配置样式,甚至深入了解了自定义样式功能以及如何使用全局样式变体覆盖所有默认值。希望您已经了解到 theme.json 在 WordPress 的区块主题时代是多么强大。

本系列的下一篇文章将更深入地介绍样式引擎。我们已经多次提到它,但只简要描述了它的作用。它是区块主题拼图中不可或缺的一部分,因为它将我们编写的 JSON 转换为普通的 CSS 代码。

它是管理区块主题 CSS 的单一事实来源。了解 WordPress 在渲染主题时幕后的工作原理是个好主意,所以让我们继续下一篇文章吧!