WordPress の theme.json ファイルに記述する内容
WordPressのtheme.jsonに記述する設定やスタイル、CSS変数の生成方法、プリセット、カスタムCSS、子テーマの仕組みを解説します。
WordPress の theme.json ファイルは、ブロックテーマのルートに配置する JSON ファイルです。テーマのデザイントークン(カラー、フォントサイズ、フォントファミリー、スペーシング、レイアウト幅)を一箇所で宣言することで、ブロックエディターとフロントエンドの両方が同じ値を参照できるようになります。
デザイントークンのパイプラインに慣れている方なら、このファイルの構造はすぐに理解できるでしょう。ただし、生成される CSS の場所を探したり、子テーマによってパレットの半分が消えた原因を調べたりする段階になると、戸惑う場面が出てきます。本記事では、ファイルの各部分を順に解説し、WordPress がそこから生成する CSS を示します。さらに、それらの変数を独自のスタイルシートで使う方法と、依然として手書きの CSS が必要になる場面も取り上げます。すべての例は、WordPress 6.6 で導入されたスキーマバージョン 3 を使用しています。
重要なポイント
theme.jsonには主要なトップレベルキーが 2 つあります。settingsはエディターが提供するコントロールとプリセットを決定し、stylesはページ全体、HTML 要素、個々のブロックにデフォルト値を適用します。- デュオトーンフィルターを除くすべてのプリセットは、
--wp--preset--{category}--{slug}という名前の CSS カスタムプロパティになります。たとえばスラッグがinkのパレットカラーは、どのスタイルシートからでもvar(--wp--preset--color--ink)として利用できます。 settings.custom配下の値は--wp--custom--*プロパティになります。キャメルケースはケバブケースに変換され、ネストの各階層はダブルハイフンで区切られます。- 子テーマの
theme.jsonは親テーマのものにマージされますが、子テーマで宣言したプリセットリストは親テーマのリストを完全に置き換えます。
theme.json とは?
theme.json はブロックテーマのデザイントークンファイルです。カラー、タイポグラフィ、スペーシング、レイアウト幅をここで一度だけ宣言すると、WordPress はその値を使ってエディターのコントロールを構築し、フロントエンドのスタイルシートを生成します。トップレベルの構成はシンプルで、$schema、version、settings、styles の 4 つが基本です。これに加えて、テンプレート、テンプレートパーツ、パターンディレクトリのパターンを登録するための customTemplates、templateParts、patterns があります。
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {},
"styles": {}
}
$schema に trunk の theme.json スキーマを指定しておくと、VS Code で自動補完とバリデーションが使えるようになります。
theme.json はなぜ存在するのか?
以前は、PHP の add_theme_support() フラグ、エディターの設定、フロントエンドの CSS という 3 つの要素が別々に管理され、内容がずれやすいという問題がありました。theme.json はこれらを置き換えるものです。ブロックエディターハンドブックのグローバル設定ガイドには、従来の各 add_theme_support フラグに対応する theme.json のキーがまとめられています。テーマが同じ設定を両方で行っている場合は、theme.json の値が優先されます。
| add_theme_support | theme.json での対応キー |
|---|---|
editor-color-palette | settings.color.palette |
editor-font-sizes | settings.typography.fontSizes |
disable-custom-colors | settings.color.custom: false |
custom-units | settings.spacing.units |
appearance-tools | settings.appearanceTools: true |
settings には何を書くか?
settings は、エディターが何を提供するかを制御します。具体的には、ピッカーにどのプリセットを表示するか、どの自由入力コントロールを許可するかを決めます。プリセットはオブジェクトの配列で、各オブジェクトは slug、値、表示用の name を持ちます。
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"appearanceTools": true,
"color": {
"custom": false,
"customGradient": false,
"defaultPalette": false,
"palette": [
{ "slug": "ink", "color": "#1b1f24", "name": "Ink" },
{ "slug": "accent", "color": "#3b5bdb", "name": "Accent" }
]
},
"typography": {
"customFontSize": false,
"defaultFontSizes": false,
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Small" },
{ "slug": "large", "size": "1.5rem", "name": "Large" }
],
"fontFamilies": [
{ "slug": "system", "fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", "name": "System" }
]
},
"spacing": { "blockGap": true, "units": ["px", "rem", "%"] },
"layout": { "contentSize": "720px", "wideSize": "1100px" },
"custom": { "radius": { "card": "12px" } }
}
}
color.custom、customGradient、customFontSize を false に設定すると自由入力のピッカーが削除され、編集者はテーマのプリセットからしか選択できなくなります。
バージョン 3 では defaultFontSizes: false の設定が重要です。theme.json バージョン 3 の開発者ノートによると、v3 のテーマでコアのデフォルトのフォントサイズやスペーシングサイズのスラッグを再利用できるのは、defaultFontSizes または defaultSpacingSizes を false に設定した場合に限られます。上の例で使っている small と large は、どちらもコアのスラッグです。
appearanceTools: true は、theme.json リビングリファレンスに記載されている一連のデザインツールを有効にします。fontFamilies 用に Web フォントを読み込む場合は、WordPress で Google Fonts をセルフホストする方法を参照してください。
プリセットの種類によって、出力される内容は異なります。
| キー | 生成されるもの |
|---|---|
color.palette | カスタムプロパティ 1 つとクラス 3 つ(テキスト色、背景色、ボーダー色) |
typography.fontSizes | カスタムプロパティ 1 つとクラス 1 つ |
typography.fontFamilies | カスタムプロパティ 1 つとクラス 1 つ |
spacing.spacingSizes | カスタムプロパティ 1 つのみ |
custom | --wp--custom--* プロパティ |
color.custom、customFontSize | エディター UI のみ(CSS は出力されない) |
なお、theme.json には互いに無関係な 2 つの custom キーがあるので注意してください。settings.color.custom: false はカラーピッカーを非表示にする設定です。一方、settings.custom は自由形式のオブジェクトで、その値が CSS 変数になります。
layout.contentSize と wideSize の仕組み
layout.contentSize は、制約付きレイアウト(constrained layout)内のコンテンツのデフォルト幅を設定します。layout.wideSize は、「幅広」配置のブロックの幅を設定します。
コアはこの 2 つの値を、:root 上で --wp--style--global--content-size と --wp--style--global--wide-size として公開しています。これは、Gutenberg PR #42084 でグローバルカスタムプロパティの宣言先が body から :root に移されたことによるものです。この変数を使えば、カスタムコンポーネントの幅をブロックのグリッドに揃えられます。
.site-banner {
max-width: var(--wp--style--global--wide-size);
margin-inline: auto;
}
styles には何を書くか?
styles は、3 つのレベルでデフォルト値を適用します。
- トップレベルのプロパティ:
bodyが対象です。 elements:link(aに対応)やh1〜h6などの HTML 要素が対象です。blocks:名前で指定した個々のブロックが対象です。
各レベルの詳細は、ハンドブックの styles セクションに記載されています。
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"styles": {
"color": { "text": "var(--wp--preset--color--ink)" },
"spacing": { "blockGap": "1.5rem" },
"blocks": {
"core/group": {
"color": { "text": "var(--wp--preset--color--accent)" },
"elements": {
"h2": { "typography": { "fontSize": "var(--wp--preset--font-size--large)" } }
}
}
}
}
}
出力:
body {
color: var(--wp--preset--color--ink);
}
:root :where(.wp-block-group) {
color: var(--wp--preset--color--accent);
}
:root :where(.wp-block-group h2) {
font-size: var(--wp--preset--font-size--large);
}
WordPress 6.6 以降、これらのルールは :root :where() ラッパーによって、詳細度が 0-1-0(単一のクラスと同じ)に抑えられています。そのため、同等以上の詳細度を持つテーマのルールが後から読み込まれれば、そちらが優先されます。また、link 要素と button 要素では、":hover" や ":focus" といった疑似状態のキーも使用できます。
WordPress は theme.json からどのような CSS を生成するか?
デュオトーンフィルターを除くすべてのプリセットは、--wp--preset--{category}--{slug} という名前の CSS カスタムプロパティになります。また、クラスを生成するプリセットは .has-{slug}-{category} というパターンに従います。
settings.custom 配下の値は、--wp--custom-- プロパティになります。WordPress はキャメルケースのキーをケバブケースに変換し、ネストの各階層の間に -- を挟みます。たとえば custom.lineHeight.body は --wp--custom--line-height--body になります。名前の各セグメントの意味は、ハンドブックの命名に関する FAQ で詳しく説明されています。
前述の settings と styles を使うと、グローバルスタイルシートには次のような出力が含まれます。なお、ハンドブックの例ではこれらのプロパティが body に宣言されていますが、現在のコアでは :root に宣言されます。この変更は Gutenberg PR #42084 で行われました。
:root {
--wp--preset--color--ink: #1b1f24;
--wp--preset--color--accent: #3b5bdb;
--wp--preset--font-size--large: 1.5rem;
--wp--custom--radius--card: 12px;
--wp--style--block-gap: 1.5rem;
}
.has-accent-color { color: var(--wp--preset--color--accent) !important; }
ルートの styles.spacing.blockGap の値は、--wp--style--block-gap として公開されます。編集者がこの値を変更できるかどうかは、settings.spacing.blockGap の設定によって決まります。
| 値 | ブロック間隔コントロール | gap スタイルの出力 |
|---|---|---|
true | 表示 | あり |
false | 非表示 | あり(theme.json で設定した値は引き続き適用される) |
null(デフォルト) | 非表示 | なし |
これらは通常のカスタムプロパティなので、どのスタイルシートからでも使用できます。
.pricing-card {
background: var(--wp--preset--color--ink);
color: #fff;
border-radius: var(--wp--custom--radius--card);
padding: var(--wp--style--block-gap);
font-size: var(--wp--preset--font-size--large);
}
theme.json でトークンを変更すると、このコンポーネントのスタイルも自動的に更新されます。ただし、theme.json の出力はキャッシュされるため、開発中は wp-config.php で WP_DEVELOPMENT_MODE を 'theme' に設定してください。
theme.json でできないことと、子テーマでの統合の仕組み
theme.json で扱えるのは、styles スキーマに含まれるプロパティだけです。それ以外のスタイルは CSS で記述する必要があります。
- プラグインやサードパーティの出力など、ブロック以外のマークアップのレイアウト
- アニメーション、トランジション、キーフレーム
- ブロックや要素に紐づかない任意のセレクター
- 利用可能なスタイルプロパティの範囲を超えるコンポーネントのスタイリング(CSS ファーストのアプローチについては、Bootstrap でレスポンシブな WordPress テーマを構築するガイドを参照)
style.css はテーマヘッダーを保持するため、引き続き必須です。子テーマの場合は、Template フィールドに wp-content/themes 内にある親テーマのフォルダー名を、大文字・小文字も含めて正確に指定します。詳しくは、テーマハンドブックのメインスタイルシートのページを参照してください。
/*
Theme Name: Studio Child
Template: studio
*/
子テーマの theme.json は親テーマのものにマージされますが、子テーマで宣言したプリセットリストは親テーマのリストを完全に置き換えます。たとえば次の子テーマのファイルでは、パレットに残る色は 1 つだけになります。
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "accent", "color": "#c2255c", "name": "Accent" }
]
}
}
}
accent だけを変更したい場合は、パレット全体をコピーしたうえで、その 1 項目だけを編集します。
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "ink", "color": "#1b1f24", "name": "Ink" },
{ "slug": "accent", "color": "#c2255c", "name": "Accent" }
]
}
}
}
一方、オブジェクトのキーについては、子テーマの theme.json で宣言していないものは引き続き親テーマから継承されます。たとえば子テーマで styles.spacing.padding.top と bottom だけを設定した場合、親テーマの左右のパディングはそのまま維持されます。
スラッグが抜け落ちたことで、エディターのプレビューでは正常なのに本番サイトではコンテンツが別の色にフォールバックしてしまうことがあります。そのような場合は、フロントエンドのセッションリプレイを確認すれば、どの要素とテンプレートでプリセットが失われたかを特定できます。
まとめ
theme.json は、WordPress がカスタムプロパティ、ユーティリティクラス、詳細度の低いデフォルトルールへとコンパイルするトークンファイルです。プリセットは settings に、デフォルト値は styles に記述し、それ以外はすべて、生成された --wp-- 変数を参照する CSS で記述しましょう。
次のステップとして、自分のテーマを使用しているページをブラウザーで開き、開発者ツールで global-styles-inline-css を確認してください。そこで宣言されているプロパティを自分のファイルと照らし合わせ、欠けているトークンがあれば、スラッグまたはスキーマの記述に誤りがある可能性があります。ユーザーの目に触れる前に修正しておきましょう。
よくある質問
theme.json で変更した値がサイトに反映されないのはなぜですか?
サイトエディターで保存されたカスタマイズによって上書きされているためです。ユーザーが「外観」>「エディター」でスタイルを変更すると、WordPress はその内容を JSON としてサイトのデータベースに保存します。テーマハンドブックによると、このユーザー設定は、コアのデフォルト、親テーマの theme.json、子テーマの theme.json のいずれよりも優先されます。スタイルパネルで該当のトークンがカスタマイズされていないかを確認し、カスタマイズされていればリセットしてから、フロントエンドを再読み込みしてください。
theme.json の中に CSS を直接記述できますか?
はい、できます。WordPress 6.2 以降、theme.json では CSS 文字列を記述できます。グローバルなルールは styles.css に、ブロック単位のルールは styles.blocks 配下の各ブロックの css プロパティに記述します。ブロック単位の CSS はスタイルパネルの該当ブロックに表示され、ユーザーが編集できます。この方法で追加したテーマの CSS は、ユーザーのカスタム CSS によって上書きまたは削除される可能性があります。そのため、デザイン上欠かせないルールは、エンキューしたスタイルシートに記述してください。
クラシックな PHP テーマでも theme.json を使えますか?
はい、使えます。クラシックテーマに theme.json を追加すると、add_theme_support を呼び出さなくても、ブロックエディターの設定やプリセットを構成できます。このような構成は、コミュニティではハイブリッドテーマと呼ばれています。ただし、WordPress がブロックテーマとして扱うのは templates/index.html を含むテーマだけなので、theme.json を追加してもブロックテーマにはなりません。テーマに add_theme_support の呼び出しが一部残っている場合は、theme.json 内の対応する設定のほうが優先されます。
PHP で theme.json の値を読み取るにはどうすればよいですか?
settings の値は wp_get_global_settings() で、styles の値は wp_get_global_styles() で取得します。どちらの関数もパスの配列を引数に取ります。たとえば wp_get_global_settings( array( 'color', 'palette', 'theme' ) ) を呼び出すと、テーマのパレット項目だけが返されます。また、block_name キーを含むコンテキスト配列を渡すと、取得対象を特定のブロックに絞り込めます。デフォルトでは、取得結果にユーザーのカスタマイズも含まれます。コアとテーマの値だけを取得したい場合は、コンテキスト配列で origin を 'base' に設定してください。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k