各位观众老爷,大家好!今天咱们来聊聊WordPress主题开发中一个挺有意思的部分——Block的CSS变量,以及theme.json
是如何神奇地变身为CSS变量的。保证让大家听完之后,感觉自己也能玩转WordPress主题的高级定制!
开场白:CSS变量,前端开发的救星!
在没有CSS变量(也叫自定义属性)的年代,咱们前端攻城狮们修改一个主题颜色,那简直就是一场灾难。找到所有用到这个颜色的地方,一个个修改,稍不留神就漏掉一个,然后就等着被UI设计师追着砍吧。
但是有了CSS变量,世界瞬间美好了!只需要在一个地方定义变量,然后在需要的地方引用,改起来不要太爽!
啥是theme.json
?主题的“大脑”!
在WordPress的Block主题中,theme.json
就是一个声明主题样式的核心文件。它定义了主题的颜色、排版、间距等等,相当于主题的“大脑”,告诉WordPress怎么去渲染各个Block。
theme.json
长得大概是这个样子(简化版):
{
"version": 2,
"settings": {
"color": {
"palette": [
{
"slug": "primary",
"color": "#007bff",
"name": "Primary"
},
{
"slug": "secondary",
"color": "#6c757d",
"name": "Secondary"
}
],
"gradients": [
{
"slug": "vivid-cyan-blue-to-vivid-purple",
"gradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)",
"name": "Vivid Cyan Blue to Vivid Purple"
}
]
},
"typography": {
"fontSizes": [
{
"slug": "small",
"size": "12px",
"name": "Small"
},
{
"slug": "normal",
"size": "16px",
"name": "Normal"
}
]
},
"spacing": {
"units": ["px", "%", "em", "rem", "vw", "vh"]
}
},
"styles": {
"elements": {
"button": {
"color": {
"background": "var(--wp--preset--color--primary)"
},
"typography": {
"fontSize": "var(--wp--preset--font-size--normal)"
}
}
},
"blocks": {
"core/paragraph": {
"typography": {
"lineHeight": "1.7"
}
}
}
}
}
theme.json
如何变成CSS变量?WordPress的魔法!
WordPress在渲染页面的时候,会解析theme.json
文件,然后把它里面的配置转换成CSS变量,注入到页面的<head>
标签中。这个过程有点像魔法,咱们一起来扒一扒它背后的原理。
-
解析
theme.json
: WordPress首先会读取并解析theme.json
文件,将其转化为一个PHP数组。 -
生成CSS变量: 然后,它会遍历这个PHP数组,根据一定的规则生成CSS变量。这些变量的命名通常遵循一个模式:
--wp--preset--<type>--<slug>
,其中:wp
:表示WordPresspreset
:表示预设值type
:表示类型,比如color
、font-size
等slug
:表示预设的唯一标识符
例如,上面例子中的
Primary
颜色,会被转换成--wp--preset--color--primary
。 -
注入到页面: 最后,WordPress会将生成的CSS变量以
<style>
标签的形式注入到页面的<head>
标签中。
代码示例:手动模拟theme.json
到CSS变量的转换!
为了更直观地理解这个过程,咱们来写一段PHP代码,模拟theme.json
到CSS变量的转换。
<?php
$theme_json = [
"version" => 2,
"settings" => [
"color" => [
"palette" => [
[
"slug" => "primary",
"color" => "#007bff",
"name" => "Primary"
],
[
"slug" => "secondary",
"color" => "#6c757d",
"name" => "Secondary"
]
],
"gradients" => [
[
"slug" => "vivid-cyan-blue-to-vivid-purple",
"gradient" => "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)",
"name" => "Vivid Cyan Blue to Vivid Purple"
]
]
],
"typography" => [
"fontSizes" => [
[
"slug" => "small",
"size" => "12px",
"name" => "Small"
],
[
"slug" => "normal",
"size" => "16px",
"name" => "Normal"
]
]
],
"spacing" => [
"units" => ["px", "%", "em", "rem", "vw", "vh"]
]
],
"styles" => [
"elements" => [
"button" => [
"color" => [
"background" => "var(--wp--preset--color--primary)"
],
"typography" => [
"fontSize" => "var(--wp--preset--font-size--normal)"
]
]
],
"blocks" => [
"core/paragraph" => [
"typography" => [
"lineHeight" => "1.7"
]
]
]
]
];
function generate_css_variables($theme_json) {
$css = ":root {n";
// 处理颜色
if (isset($theme_json['settings']['color']['palette'])) {
foreach ($theme_json['settings']['color']['palette'] as $color) {
$css .= " --wp--preset--color--" . $color['slug'] . ": " . $color['color'] . ";n";
}
}
// 处理渐变
if (isset($theme_json['settings']['color']['gradients'])) {
foreach ($theme_json['settings']['color']['gradients'] as $gradient) {
$css .= " --wp--preset--gradient--" . $gradient['slug'] . ": " . $gradient['gradient'] . ";n";
}
}
// 处理字体大小
if (isset($theme_json['settings']['typography']['fontSizes'])) {
foreach ($theme_json['settings']['typography']['fontSizes'] as $fontSize) {
$css .= " --wp--preset--font-size--" . $fontSize['slug'] . ": " . $fontSize['size'] . ";n";
}
}
// 处理间距单位
if (isset($theme_json['settings']['spacing']['units'])) {
// 咱们这里只是简单地输出,实际WordPress会做更复杂的处理
$css .= " /* Spacing units: " . implode(", ", $theme_json['settings']['spacing']['units']) . " */n";
}
$css .= "}n";
return $css;
}
$css_variables = generate_css_variables($theme_json);
echo "<style>n";
echo $css_variables;
echo "</style>n";
?>
这段代码会生成如下的CSS:
:root {
--wp--preset--color--primary: #007bff;
--wp--preset--color--secondary: #6c757d;
--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);
--wp--preset--font-size--small: 12px;
--wp--preset--font-size--normal: 16px;
/* Spacing units: px, %, em, rem, vw, vh */
}
是不是感觉豁然开朗? WordPress的核心逻辑也差不多就是这样,只不过它会处理更多类型的配置,并且会进行更复杂的优化。
theme.json
中的styles
节点:Block的个性化定制!
除了settings
节点,theme.json
中还有一个styles
节点,它可以用来定制特定Block的样式。
styles.elements
: 用于设置通用HTML元素(如button
、link
)的样式。styles.blocks
: 用于设置特定Block(如core/paragraph
、core/heading
)的样式。
styles
节点中的样式可以直接使用settings
节点中定义的CSS变量,也可以定义新的CSS变量,或者直接设置CSS属性。
例如,上面的例子中,我们给button
元素设置了背景颜色和字体大小,给core/paragraph
Block设置了行高。
代码示例:styles
节点如何影响CSS变量?
咱们来扩展一下上面的PHP代码,模拟styles
节点对CSS变量的影响。
<?php
// ... (之前的$theme_json定义)
function generate_css_variables($theme_json) {
$css = ":root {n";
// ... (之前的颜色、渐变、字体大小处理)
// 处理样式(elements)
if (isset($theme_json['styles']['elements'])) {
foreach ($theme_json['styles']['elements'] as $element => $styles) {
$css .= " /* Styles for element: " . $element . " */n";
if (isset($styles['color']['background'])) {
$css .= " --wp--style--element--" . $element . "--background-color: " . $styles['color']['background'] . ";n";
}
if (isset($styles['typography']['fontSize'])) {
$css .= " --wp--style--element--" . $element . "--font-size: " . $styles['typography']['fontSize'] . ";n";
}
}
}
// 处理样式(blocks)
if (isset($theme_json['styles']['blocks'])) {
foreach ($theme_json['styles']['blocks'] as $block => $styles) {
$css .= " /* Styles for block: " . $block . " */n";
if (isset($styles['typography']['lineHeight'])) {
$css .= " --wp--style--block--" . str_replace('/', '-', $block) . "--line-height: " . $styles['typography']['lineHeight'] . ";n";
}
}
}
$css .= "}n";
return $css;
}
$css_variables = generate_css_variables($theme_json);
echo "<style>n";
echo $css_variables;
echo "</style>n";
?>
这段代码会生成如下的CSS(在之前的基础上新增):
:root {
--wp--preset--color--primary: #007bff;
--wp--preset--color--secondary: #6c757d;
--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);
--wp--preset--font-size--small: 12px;
--wp--preset--font-size--normal: 16px;
/* Spacing units: px, %, em, rem, vw, vh */
/* Styles for element: button */
--wp--style--element--button--background-color: var(--wp--preset--color--primary);
--wp--style--element--button--font-size: var(--wp--preset--font-size--normal);
/* Styles for block: core/paragraph */
--wp--style--block--core-paragraph--line-height: 1.7;
}
注意,这里为了区分,styles
节点生成的CSS变量的命名规则略有不同:
--wp--style--element--<element>--<property>
:用于通用HTML元素--wp--style--block--<block-name>--<property>
:用于特定Block,注意Block名称中的/
被替换成了-
。
实战演练:自定义Block样式!
现在,咱们来做一个简单的实战演练,自定义core/heading
Block的样式。
-
修改
theme.json
: 在theme.json
的styles.blocks
节点中,添加core/heading
的样式:{ "version": 2, "settings": { // ... (省略) }, "styles": { // ... (省略) "blocks": { // ... (省略) "core/heading": { "color": { "text": "var(--wp--preset--color--secondary)" }, "typography": { "fontWeight": "bold" } } } } }
-
查看生成的CSS变量: WordPress会自动生成如下的CSS变量:
:root { // ... (省略) --wp--style--block--core-heading--color--text: var(--wp--preset--color--secondary); --wp--style--block--core-heading--typography--font-weight: bold; }
-
应用样式: WordPress会自动将这些CSS变量应用到
core/heading
Block上。 当然,它不是直接内联样式,而是通过CSS选择器来实现的。 具体的选择器规则比较复杂,但大致思路是: 找到页面中所有的core/heading
Block,然后应用这些CSS变量。
高级技巧:利用theme.json
控制全局样式!
theme.json
不仅仅可以用来设置颜色、字体等基本样式,还可以用来控制一些更高级的全局样式,比如:
- 响应式设计: 可以通过
media
查询来设置不同屏幕尺寸下的样式。 - 状态样式: 可以设置
:hover
、:focus
等状态下的样式。 - 暗黑模式: 可以通过
prefers-color-scheme
媒体查询来设置暗黑模式下的样式。
总结:theme.json
,主题开发的利器!
通过今天的讲座,相信大家对theme.json
如何转换为CSS变量已经有了一个清晰的认识。
theme.json
是WordPress Block主题开发的核心,它通过一种声明式的方式,将主题的样式配置集中管理,并且可以轻松地生成CSS变量,方便咱们前端攻城狮们进行主题的定制和扩展。
掌握了theme.json
,就等于掌握了WordPress Block主题开发的钥匙,可以让你在主题定制的道路上越走越远!
最后,给大家留个小作业:
尝试修改你自己的theme.json
文件,添加一些自定义的颜色、字体,然后观察页面上的变化,加深对theme.json
和CSS变量的理解。
祝大家学习愉快!咱们下次再见!