WordPress Logo ブロックスタイルとブロックバリエーション

ブロックテーマ制作でブロックをカスタマイズする機能として、登録したブロックのスタイルをボタンで切り替えることのできるブロックスタイルバリエーションや、ブロックがページで使用されている場合にのみその CSS を読み込むブロックスタイルシート、既存のブロックを拡張してインサーターに追加できるブロックバリエーションなどがあります。

以下は WordPress ブロックテーマシステムでサポートされている「ブロックスタイル」や「ブロックスタイルシート」、「ブロックバリエーション」について、公式ドキュメント Theme Handbook の Features(英語版)をもとに個人的にまとめたものです。使用している WordPress のバージョンは 6.6.2 です。

関連ページ

更新日:2024年10月21日

作成日:2024年10月19日

ブロックスタイルバリエーション

ブロックスタイルバリエーション (略してブロックスタイル) を使用すると、個々のブロックに代替スタイルを作成できます。登録されたスタイルはユーザーインターフェイス(スタイルパネル)に表示され、ユーザーは既定のスタイルと代替スタイルをボタンをクリックするだけで簡単に切り替えることができます。

「バリエーション」という用語

多くの機能の名前に「バリエーション」という用語が使用されていますが、ブロックスタイルバリエーションは、グローバルスタイルバリエーションブロックバリエーションと同じではありません。

また、ブロックスタイルバリエーションは単にブロックスタイルと呼ばれますが、ブロックスタイルシートとは異なります(この2つの機能は連携して使用できますが同じものではありません)。

以降では、ブロックスタイルバリエーションは省略してブロックスタイルとしています。

ブロックスタイルとは

ブロックスタイルは内部的には、ブロックのラップ要素に .is-style-{name} という名前で追加された CSS クラスでカスタムスタイルを追加してブロックのデザインを変更します。

ブロックスタイルはブロックにクラスを追加して CSS でカスタマイズするための標準的な方法です。

以下のスクリーンショットでは、画像ブロックのスタイルパネルに「デフォルト」と「角丸」2つのブロックスタイル(バリエーション)が表示されていて、「角丸」オプションが選択されています。

上記の例では WordPress 本体により登録されている画像ブロックのブロックスタイル(デフォルトと角丸)だけが表示されていますが、テーマ側でもブロックスタイルを登録することができ、ユーザーがそれらのスタイルのいずれかを選択すると、登録されたスタイルの CSS がブロックに適用されます。

ユーザーは一度に1つのスタイルのみブロックに適用できます。より多くのオプションを許可する必要がある場合は、カスタムデザインツールを作成する必要があります。

参考:Beyond Block Styles

ブロックスタイルには、PHP で登録する方法(PHP-based block styles)と JavaScript 経由でブロックスタイルを操作する方法(JavaScript-based block styles)があります。

PHP-based block styles

以下は、ブロックスタイルを PHP で登録する方法です。

JavaScript 経由でブロックスタイルを操作する必要がある場合は、JavaScript-based block styles を御覧ください。

ブロックスタイルを PHP で登録

ブロックスタイルを登録するには、register_block_style() 関数を使用します。

以下は register_block_style() 関数の書式です。

register_block_style(
  string $block_name,
  array $style_properties
)

この関数は2つのパラメータを受け入れ、登録が成功したかどうかに応じて true または false を返します。

パラメータ 説明
$block_name 名前空間とスラッグの両方を含むブロックの名前 (例: core/image)。
$style_properties スタイルを構成するための以下のプロパティの配列。
  • name: (必須) クラスを生成するために使用される一意の名前(スラッグ)。
    is-style-{name} というクラスが生成されます。
  • label: (必須) 人間が読めるラベル。翻訳可能。
  • inline_style: スタイルの使用時に出力されるインライン CSS。
  • style_handle(※): スタイル用にロードするスタイルシートのハンドル名。
  • is_default: スタイルをブロックのデフォルトとして選択するかどうか (初期値は false)。

(※)style_handle には現在、スタイルシートをエディターにのみキューに追加し、フロントエンドには追加しないというバグがあり、解決されるまで、その使用は推奨されません。

inline_style に指定する CSS コードが数行を超える(コード量が多い)場合は、代わりに CSS をブロックスタイルシートに追加した方が良いかもしれません。

以下は画像ブロックに「手描き風」のスタイルを追加するブロックスタイルの例です。

ブロックスタイルを登録するには、register_block_style() 関数を使用して設定し、init フックのコールバックとして追加します。テーマの functions.php ファイルに記述します。

以下のままでも機能しますが、「themeslug」や「textdomain」の部分はテーマのスラッグ(フォルダ名)などに適宜変更します。

add_action('init', 'themeslug_register_block_styles');

function themeslug_register_block_styles() {
  register_block_style(
    'core/image',
    array(
      'name'         => 'hand-drawn',
      'label'        => __('手描き風', 'textdomain'),
      'inline_style' => '.wp-block-image.is-style-hand-drawn img {
        border: 2px solid currentColor;
        overflow: hidden;
        box-shadow: 0 4px  10px 0 rgba( 0, 0, 0, 0.1 );
        border-radius: 30% 17% 24% 16% / 10% 23% 10% 24% !important;
      }'
    )
  );
}

画像ブロックの画像は .wp-block-image img なので、inline_style のセレクタは、is-style-{name} クラスを指定した画像ブロックの子要素の img なので、.wp-block-image.is-style-hand-drawn img となります。ブロックに付与されるクラス名(例 wp-block-image)はブラウザのインスペクタで確認できます。

上記を登録して、投稿の編集画面で画像を選択すると、スタイルパネルに「手描き風」というボタンが表示され、選択するとスタイルが適用されます。

inline_style に指定したスタイルは、<head> 要素内に画像ブロック用のその他のスタイルとともに出力されます。

<style id='wp-block-image-inline-css'>
.wp-block-image img{box-sizing:border-box;height:auto;max-width:100%;vertical-align:bottom}
/* その他の画像ブロックのスタイル */
.wp-block-image.is-style-hand-drawn img {
  border: 2px solid currentColor;
  overflow: hidden;
  box-shadow: 0 4px  10px 0 rgba( 0, 0, 0, 0.1 );
  border-radius: 30% 17% 24% 16% / 10% 23% 10% 24% !important;
}
</style>

以下は前述の例に、ボタンブロックのブロックスタイル(角丸なし)を追加した例です。

ボタンの角丸は、フロントエンドではボタンブロック(.wp-block-button)の子要素の a 要素に、エディター側ではボタンブロックの子要素の div 要素に指定されているのでセレクタを2つ記述しています。

add_action('init', 'themeslug_register_block_styles');

function themeslug_register_block_styles() {

  register_block_style(
    'core/image',
    array(
      'name'         => 'hand-drawn',
      'label'        => __('手描き風', 'textdomain'),
      'inline_style' => '.wp-block-image.is-style-hand-drawn img {
        border: 2px solid currentColor;
        overflow: hidden;
        box-shadow: 0 4px  10px 0 rgba( 0, 0, 0, 0.1 );
        border-radius: 30% 17% 24% 16% / 10% 23% 10% 24% !important;
      }'
    )
  );

  // ボタンブロックのブロックスタイル(角丸なし)
  register_block_style(
    'core/button',
    array(
      'name'         => 'square-button',
      'label'        => __('角ボタン', 'textdomain'),
      'inline_style' => '.wp-block-button.is-style-square-button a,
      .wp-block-button.is-style-square-button div { border-radius: 0px !important; }',
    )
  );

}

WordPress によって設定されているブロックスタイル「塗りつぶし」と「輪郭」は theme.json でカスタマイズすることができます。

ブロック名

register_block_style() 関数の第1引数などに指定する「core/image」などのブロック名は以下のページにブロックのリストが掲載されているので確認できます。

Core Blocks Reference

または、ブロックエディター(編集画面)を開き、ブラウザーのコンソールを起動して、wp.blocks.getBlockTypes() と入力すると、ブロック名のリストが表示されます。getBlockTypes() は使用可能なすべてのブロックタイプを返します。

クラス名

出力されるブロックの要素に指定されるクラス名は、通常、.wp-block-{slug} になります。slug はブロック名の core などの名前空間とスラッシュ以外の部分です(core/image なら .wp-block-image)。

PHP でブロックスタイルの登録解除

PHP で登録したブロックスタイルの登録を解除するには、unregister_block_style() 関数を使用します。

unregister_block_style(
  string $block_name,
  string $block_style_name
)

この関数は2つのパラメータを受け入れ、登録が成功したかどうかに応じて true または false を返します。

パラメータ 説明
$block_name 名前空間とスラッグの両方を含むブロックの名前 (例: core/image)。
$block_style_name PHP 経由で登録されたブロックスタイルの名前(register_block_style() で登録した際に指定した第2引数の name プロパティの値)。

以下は、前述のブロックスタイルを PHP で登録で登録したブロックスタイル 'hand-drawn' の登録を解除する例です。

登録を解除する場合、init フックで unregister_block_style() を呼び出します。その際、登録関数 (デフォルトは 10) の後に実行されるように、この例では優先度を 999 としています。

add_action( 'init', 'themeslug_unregister_block_styles', 999 );

function themeslug_unregister_block_styles() {
  unregister_block_style( 'core/image', 'hand-drawn' );
}

※ ブロックスタイルは、PHP 経由で登録されている場合にのみ、PHP で登録解除できます。ブロックスタイルが JavaScript で登録されている場合は、JavaScript を使用して登録解除する必要があります。

例えば、WordPress により登録されているボタンブロックの輪郭(outline)は、JavaScript で登録されているので、以下のように PHP で登録を解除しようとしてもできません。

add_action( 'init', 'themeslug_unregister_block_styles', 999 );

function themeslug_unregister_block_styles() {
  // 以下のブロックスタイルは JavaScript で登録されているので PHP では解除できない
  unregister_block_style( 'core/button', 'outline' );
}

ボタンブロックの輪郭(outline)の登録を解除するには、JavaScript でブロックスタイルを登録解除する必要があります。

JavaScript-based block styles

JavaScript 経由でブロックスタイルを登録または登録解除するには、enqueue_block_editor_assets フックで JavaScript ファイルを読み込む必要があります。

この例では、テーマに /assets/js/ フォルダを作成し、その中に block-editor.js ファイルを作成します。ファイル名や場所は任意ですが、以下の例ではこのファイル名と場所を前提としています。

そして functions.php ファイルに以下を記述して、wp_enqueue_script() を使って block-editor.js を読み込みます。themeslug の部分はテーマのスラッグなどに適宜変更します(以下のままでも機能します)。

add_action('enqueue_block_editor_assets', 'themeslug_block_editor_assets');

function themeslug_block_editor_assets() {
  wp_enqueue_script(
    'themeslug-block-editor',
    get_theme_file_uri('assets/js/block-editor.js'),
    // 依存するスクリプトのハンドル名の配列
    array(
      'wp-blocks',
      'wp-dom-ready',
      'wp-edit-post'  // この例の場合は、省略可能
    )
  );
}
ブロックスタイルを JavaScript で登録

JavaScript でブロック スタイルを登録するには、registerBlockStyle() 関数を使用します。

registerBlockStyle() 関数は、block-editor.js の読み込みで依存関係に指定した wp-blocks から取得され、関数の前に wp.block. を付けることで呼び出すことができます。

registerBlockStyle() は、PHP 関数の register_block_style() と同様に機能しますが、JavaScript 構文を使用します。

wp.blocks.registerBlockStyle(
  'ブロック名', // 名前空間とスラッグの両方を含むブロックの名前
  {
    name: '名前', // クラスを生成するために使用される一意の名前
    label: 'ラベル', // 人間が読めるラベル
    isDefault: '真偽値', // スタイルをブロックのデフォルトとして選択するかどうかの真偽値(初期値は false)
  }
);

以下は前述の PHP での例と同じ、画像ブロックに「手描き風」のスタイルを追加するブロックスタイルを登録する例です。

wp.blocks.registerBlockStyle('core/image', {
  name: 'hand-drawn',
  label: '手書き',
});

上記は以下のように記述することもできます。

const { registerBlockStyle } = wp.blocks; // registerBlockStyle を wp-blocks から取得

registerBlockStyle('core/image', {
  name: 'hand-drawn',
  label: '手書き',
});
カスタム CSS の追加

PHP の register_block_style() 関数では、inline_style プロパティにカスタム CSS を追加しましたが、JavaScript で登録する場合は、ブロックスタイルシートに記述して読み込むか、他の方法で CSS を追加する必要があります。

ブロックスタイルシートを使わない場合の例

以下はテーマに /assets/css/blocks-style.css ファイルを作成し、enqueue_block_assets フックを使ってエディターとフロントエンドの両方に読み込む例です(ファイル名や配置場所は任意です)。

add_action('enqueue_block_assets', 'add_my_theme_block_styles');

function add_my_theme_block_styles() {
  wp_enqueue_style(
    'my-theme-block-styles',
    get_stylesheet_directory_uri() . '/assets/css/blocks-style.css',
    array(),
    filemtime(get_theme_file_path('/assets/css/blocks-style.css'))
  );
}

上記で読み込んだ blocks-style.css にカスタム CSS を追加します。

.wp-block-image.is-style-hand-drawn img {
  border: 2px solid currentColor;
  overflow: hidden;
  box-shadow: 0 4px  10px 0 rgba( 0, 0, 0, 0.3 );
  border-radius: 30% 17% 24% 16% / 10% 23% 10% 24%  !important;
  transition: border-radius 0.3s;
}

ブロックスタイルシートを作成して記述する場合の例

以下はテーマに /assets/blocks/core-image.css というファイルを作成し、以下を functions.php に記述して作成したブロックスタイルシートを登録します。

add_action( 'init', 'themeslug_enqueue_block_styles' );

function themeslug_enqueue_block_styles() {
  wp_enqueue_block_style( 'core/image', array(
    'handle' => 'themeslug-block-image',
    'src'    => get_theme_file_uri( "assets/blocks/core-image.css" ),
    'path'   => get_theme_file_path( "assets/blocks/core-image.css" )
  ) );
}

そして、上記のブロックスタイルシートに次のコードを追加します(前述の CSS と同じ)。

.wp-block-image.is-style-hand-drawn img {
  border: 2px solid currentColor;
  overflow: hidden;
  box-shadow: 0 4px  10px 0 rgba( 0, 0, 0, 0.3 );
  border-radius: 30% 17% 24% 16% / 10% 23% 10% 24%  !important;
  transition: border-radius 0.3s;
}

ブロックスタイルシートの詳細は、後述のブロックスタイルシートをご参照ください。

JavaScript でブロックスタイルを登録解除

PHP の unregister_block_style() 関数に相当する JavaScript の unregisterBlockStyle() という関数もあり、これを使用して JavaScript 経由で登録されたブロックスタイルを登録解除できます。

ブロックスタイルの登録を解除する際は、登録と登録解除の競合を回避するため、ブロックスタイルが登録された後に登録解除する必要があるので、wp.domReady() のコールバック内で unregister_block_style() を呼び出します(これにより、DOM が読み込まれた後に登録解除されます)。

JavaScript 経由で登録した「手描き風」ブロックスタイルを登録解除するには、/assets/js/block-editor.js ファイルに以下を追加します。

wp.domReady( function () {
  wp.blocks.unregisterBlockStyle( 'core/image', 'hand-drawn' );
} );

unregisterBlockStyle() 関数は registerBlockStyle() 関数同様、block-editor.js の読み込みで依存関係に指定した wp-blocks から、domReady() は依存関係に指定した wp-dom-ready から取得されます。

※ ブロック スタイルは、JavaScript 経由で登録されている場合のみ、JavaScript で登録解除できます。ブロック スタイルが PHP で登録されている場合は、PHP を使用して登録解除する必要があります

theme.json でブロックスタイルをカスタマイズ

以下のコアブロックには WordPress 本体によりブロックスタイルが設定されており、theme.json でカスタマイズすることができます。

  • core/button : outline, fill(輪郭、塗りつぶし)
  • core/image : rounded(角丸)
  • core/quote : plain(プレーン)
  • core/site-logo : rounded(角丸)
  • core/separator : wide, dots(幅広線、ドット)
  • core/social-links : logos-only, pill-shape(ロゴのみ、カプセル型)
  • core/table : stripes(ストライプ)
  • core/tag-cloud : outline(輪郭)

例えば、画像ブロックには角丸というブロックスタイルが設定されています。

画像ブロック(core/image)の角丸(rounded)ブロックスタイルをカスタマイズするには、theme.json で styles.blocks.core/image.variations.rounded プロパティをターゲットにします。

例えば、border-radius の値を 20px に変更するには、以下のように border プロパティの radius プロパティを設定します(以下はその他の設定は省略しています)。

{
  "version": 3,
  "styles": {
    "blocks": {
      "core/image": {
        "variations": {
          "rounded": {
            "border": {
              "radius": "20px"
            }
          }
        }
      }
    }
  }
}

上記を設定して「角丸」を選択すると、以下のように角丸の値が 20px に変更されます。

関連ページ:theme.json v3 設定と使い方/ブロックのスタイル設定

Create Block Theme プラグインを利用

前述のように手動で theme.json を編集できますが、Create Block Theme プラグインを利用すると簡単です。以下は Create Block Theme プラグインがインストールされていることを前提にしています。

以下は、画像ブロックの角丸ブロックスタイルの border-radius の値を 20px に変更する例です。

管理画面の「外観」→「エディター」でサイトエディターを開き、左側のメニューから「スタイル」を選択します。そしてサイドバーのスタイルブックのアイコンをクリックします。

「メディア」タブを選択し、スタイルバリエーションの「角丸」をクリックします。

サイドバーの「角丸」の値を設定します。必要に応じて枠線やドロップシャドウなども設定できます。

右上の「保存」をクリックすると、以下が表示されるので「保存」をクリックします。これによりカスタマイズした内容はユーザーカスタマイゼーションとしてデータベースに保存されます。

「保存」ボタンの右にあるアイコン()をクリックし、「テーマへの変更を保存」をクリックします。

以下が表示されるので、「スタイル変更を保存」がチェックされていることを確認して、一番下の「変更内容を保存」をクリックします。

以下が表示されたら、「OK」をクリックします。

これでテーマの theme.json に styles.blocks.core/image.variations.rounded.border.radius プロパティ(前述の例で手動で追加したのと同じ内容)が追加されます。

データベースに保存されたカスタマイゼーションはクリアされます。

関連ページ:Create Block Theme プラグインの使い方

ブロックスタイルシート

ブロックをスタイリングするときは、可能であれば常に theme.json のスタイルプロパティを使用することが推奨されています。これにより、デフォルトの WordPress スタイル、プラグインによるスタイル、及びユーザーのカスタマイズと連携して、システム全体でスタイルの互換性が最大限に確保されます。

但し、theme.json は JSON ファイルなので改行をサポートしていないため、すべてを1行に記述する必要があり、複雑な CSS を記述するのには向いていません。

そのような場合など、必要に応じてブロックスタイルシートを使用します。

カスタムスタイルをテーマの style.css ファイルに入れることもできますが、ブロックスタイルシートシステムでは、ブロックがページで使用されている場合にのみブロックの CSS を読み込むことで、パフォーマンスの向上が期待でき、フロントエンドでは、コードは <head> 領域内にインライン化されます。

また、ブロックごとに個別のスタイルシートを作成するのでコードの整理と管理が容易になります。

ブロックスタイルシートの作成

以下はブロックスタイルシートを作成する大まかな手順です。

  1. 命名スキーム(配置場所とファイル名)を決定します。
  2. カスタム CSS を記述します。
  3. カスタム ブロックスタイルシートを登録します。
配置場所とファイル名

ブロックスタイルシートは任意の場所 (標準的な場所はありません) に配置することができます。以下のコードでは、テーマの /assets/blocks フォルダーに配置することを前提としています。

CSS ファイルの標準的な命名規則もありませんが、以下ではブロックの名前空間とスラッグを使って {namespace}-{slug}.css のようにしています。例えば、core/group ブロックのスタイルシートは core-group.css になります。

以下は3つのブロックスタイルシートを配置した場合の構成例です。

assets
  └── blocks
        ├── core-group.css
        ├── core-image.css
        └── core-media-text.css
CSS を追加

ブロックの CSS クラスは、ブロックの名前空間とスラッグに応じて、.wp-block-{namespace}-{slug} の形式で自動的に生成されるので、このクラス名を使ってセレクタを指定します。

例えば、名前空間とスラッグが super/duper のブロックのスタイル設定は以下のように記述します。

.wp-block-super-duper {
  /* カスタム CSS をここに記述します */
}

コアブロックのクラス命名規則

コアブロックの命名規則は例外で、コアブロックの名前空間は core ですが、core は CSS クラスには含まれません。そのため、コアブロックの CSS クラスは .wp-block-{slug} 形式を使用します。

例えば、画像ブロックは core/image の名前空間とスラッグを持つので、画像ブロックにカスタムスタイルを追加するには .wp-block-image をターゲットにします。

サードパーティのブロック

上記の一般的なガイドはサードパーティのブロックに必ずしも当てはまらない場合があります。その場合は、ソースコードでブロックの CSS クラスを見つける必要があります。

設定例

以下は画像ブロック(core/image)のカスタム CSS の例です。

テーマに /assets/blocks/core-image.css ファイルを作成し、次のカスタムスタイルを追加します。

画像ブロックの画像要素(img)にパディングとグラデーションの背景を設定し、リンクが設定されている場合はトランジションアニメーションでホバー時にオパシティを変更しています。

もし、1行目のセレクタを .wp-block-image.gradient-bg img とすれば、編集画面の「高度な設定」→「追加CSSクラス」に gradient-bg を指定した場合のみ、グラデーションの背景を表示することができます。

.wp-block-image img {
  padding: 1rem;
  background: linear-gradient(-60deg,#f9f343,#f53be6);
}

.wp-block-image a img {
  transition:opacity .3s;
}

.wp-block-image a img:hover {
  opacity: .9;
}

但し、CSS を追加しただけでは、エディターやフロントエンドには反映されません。

このカスタムスタイルをエディターやフロントエンドに適用させるには、ブロックスタイルシートとして登録する必要があります。

ブロックスタイルシートの登録

ブロックスタイルシートを登録するには、init フックで wp_enqueue_block_style() 関数を使用します。

wp_enqueue_block_style( string $block_name, array $args )

wp_enqueue_block_style() 関数は、次の2つのパラメータを受け入れます。

パラメータ 説明
$block_name 名前空間とスラッグの両方を含むブロックの名前 (例: core/image)。
$args

wp_register_style() に渡される引数の配列(以下)

  • handle: スタイルシートのハンドル名。
  • src: スタイルシートの URL。
  • path: スタイルシートへの絶対パス(※)。
  • deps: このスタイルシートが依存する登録済みスタイルシートのハンドル名の配列。
  • ver: スタイルシートのバージョン番号。
  • media: スタイルシートが定義されているメディア。

(※)他の wp_enqueue_* 関数とは異なり、URL パスとともに CSS ファイルへのファイルパスを指定する必要があります。これは、WordPress がファイルのコンテンツを取得して <head> 要素内に出力する必要があるためです。

前項で作成した画像ブロックのカスタムブロックスタイルシートを登録するには、functions.php ファイルに次のコードを追加します。以下のままでも機能しますが、themeslug の部分はテーマのスラッグなどに適宜変更します。

add_action( 'init', 'themeslug_enqueue_block_styles' );

function themeslug_enqueue_block_styles() {
  wp_enqueue_block_style( 'core/image', array(
    'handle' => 'themeslug-block-image',
    'src'    => get_theme_file_uri( "assets/blocks/core-image.css" ),
    'path'   => get_theme_file_path( "assets/blocks/core-image.css" )
  ) );
}

上記は WordPress がサイトの <head> 内に CSS コードをインライン化するために必要な最小限のパラメータを指定しています。必要に応じて、wp_enqueue_block_style() の呼び出しに追加のパラメータ(deps や ver、media)を設定することもできます。

ブロックスタイルシートを登録して、投稿に画像を挿入すると、この例の場合、以下のように画像にパディングとグラデーションの背景色が適用されます。

複数スタイルシートの登録

複数のブロックスタイルシートを登録する場合は配列を使用してループします。

例えば、コアのボタン、見出し、画像ブロックのスタイルシートが以下のように配置されている場合、

assets
  └── blocks
        ├── core-button.css
        ├── core-heading.css
        └── core-image.css

以下のように「名前空間/スラッグ」形式のブロック名の配列を用意して、foreach() を使ってブロックスタイルシートを登録することができます。themeslug の部分は適宜変更します。

add_action( 'init', 'themeslug_enqueue_block_styles' );

function themeslug_enqueue_block_styles() {
  // '名前空間/スラッグ' 形式のブロック名の配列
  $blocks = array(
      'core/button',
      'core/heading',
      'core/image',
  );

  // 上記ブロック名の配列をループして wp_enqueue_block_style() で登録
  foreach ( $blocks as $block ) {
      // スラッシュをハイフンに置換
      $slug = str_replace( '/', '-', $block );
      wp_enqueue_block_style( $block, array(
          'handle' => "themeslug-block-{$slug}",
          'src'    => get_theme_file_uri( "assets/blocks/{$slug}.css" ),
          'path'   => get_theme_file_path( "assets/blocks/{$slug}.css" )
      ) );
  }
}

ファイルの配列を自動的に生成

上記の例の場合、ブロックスタイルシートを追加したり削除する度にコードを書き換えなければなりませんが、PHP の glob() 関数を使用してファイルの配列を自動的に生成することができます。

以下はブロックスタイルシートのファイル名が「名前空間-スラッグ.css」形式になっていて、テーマの /assets/blocks/ フォルダに配置されていることを前提にしています。

前述のコードは以下に置き換えることができます(themeslug の部分は適宜変更します)。

add_action('init', 'themeslug_enqueue_block_styles');

function themeslug_enqueue_block_styles() {
  // ブロックスタイルシートのディレクトリ(テーマディレクトリからのパス)
  $block_directory = '/assets/blocks/';
  // ブロックスタイルシートのディレクトリの絶対パス
  $path = get_stylesheet_directory() . $block_directory;
  // 全てのブロックスタイルシートのパス(配列)
  $file_paths =  glob($path . '*.css');

  // ブロックスタイルシートのパスの配列をループして wp_enqueue_block_style() で登録
  foreach ($file_paths as $file_path) {
    // パスと拡張子を除いたファイル名部分の文字列(例 core-image)
    $slug = str_replace([$path, '.css'], '', $file_path);
    // $slug からブロック名を作成(例 core/image)
    $blockname = str_replace('-', '/', $slug);

    wp_enqueue_block_style(
      $blockname,
      array(
        'handle' => "themeslug-block-{$slug}",
        'src'    => get_theme_file_uri($block_directory . "{$slug}.css"),
        'path'   => get_theme_file_path($block_directory . "{$slug}.css")
      )
    );
  }
}

参考:Leveraging theme.json and per-block styles for more performant themes

ブロックバリエーション

ブロックバリエーション API は、既存のブロックを拡張できる機能で、既存ブロックの初期属性やネストしたブロックのセットが異なる代替バージョンを作成することができます。

基本的には CSS で可能なカスタマイズは前述のブロックスタイルバリエーションを使用し、初期属性やネストしたブロック(inner block)を適用する場合はブロックバリエーションを使います。

セットアップ: JavaScript の読み込み

ブロックのバリエーションは JavaScript で登録されるため、まず JavaScript ファイルを作成します。この例ではテーマにブロックバリエーションを追加しますが、プラグインとして追加することもできます(違いは、ファイルと関数が配置されている場所です)。

JavaScript を追加するファイル block-variations.js を作成し、テーマの /assets/js/ フォルダーに配置します(ファイルやフォルダーは任意の名前を付けられます)。

assets
    └── js
        └── block-variations.js

作成したファイルをエディターに読み込むには、enqueue_block_editor_assets フックと wp_enqueue_script() 関数を使用して、block-variations.js をキューに追加します。

以下を functions.php に記述します。「themeslug」の文字列部分は適宜変更します。

add_action('enqueue_block_editor_assets', 'themeslug_enqueue_block_variations');

function themeslug_enqueue_block_variations() {
  wp_enqueue_script(
    'themeslug-block-variations',
    get_theme_file_uri('assets/js/block-variations.js'),
    // 依存するスクリプトのハンドル名の配列
    array(
      'wp-blocks',
      'wp-dom-ready',
      'wp-i18n'  // 翻訳関数を使わない場合は不要
    ),
    wp_get_theme()->get('Version'),
    true  // false または省略しても OK
  );
}

wp_enqueue_script() の3番目のパラメータ (依存関係配列) には、block-variations.js でブロックバリエーションを登録および登録解除するために使用する wp-blocks、wp-dom-ready、及び多言語化で使用する wp-i18n スクリプト(パッケージ)を指定しています。

依存スクリプト 説明(取得する関数)
wp-blocks 登録の registerBlockVariation() と登録解除の unregisterBlockVariation()
wp-dom-ready 登録解除で使用する domReady()
wp-i18n 多言語化で使用する __()

ブロックバリエーションの登録

block-variations.js ファイルをキューに入れたら、registerBlockVariation() 関数を使用してブロックバリエーションを登録できます。

registerBlockVariation() 関数は元になるブロックの名前(blockName)と作成するバリエーションを定義するオブジェクト(variation)の2つのパラメータを受け入れます。

registerBlockVariation( blockName, variation ) 
パラメータ 説明
blockName バリエーションを登録するブロックの名前 (名前空間を含む)。 例: core/spacer
variation

バリエーションを構成するためのオプションのオブジェクト。次のプロパティのいずれかを含めることができます。

  • name: バリエーションの一意なスラッグ。
  • title: バリエーションの人間が読めるタイトル(翻訳可能)。
  • description: バリエーションの人間が読める説明(翻訳可能)。
  • category: 登録されたブロック タイプ カテゴリのスラッグ
  • keywords: 検索時にバリエーションを見つけるのに役立つキーワードの配列。
  • icon: バリエーションを視覚化するために使用するアイコン。
  • attributes: ブロックの属性をオーバーライドするオブジェクト。
  • innerBlocks: ネストされたブロックの初期構成の配列。
  • example: ブロックプレビューに構造化データを提供するオブジェクト。プレビューを無効にするには、undefined に設定。
  • scope: ブロックを使用できるスコープのリスト。使用可能なオプションは、block、inserter、および transform。
  • isDefault: バリエーションをブロックのデフォルトバリエーションとして設定するかどうか。デフォルトは false。
  • isActive: ブロックが選択されたときにバリエーションがアクティブであるかどうかをエディタが判断するために使用される関数またはブロック属性の配列。

詳細:Variations

以下は動作確認のためのシンプルなスペーサーブロックのバリエーションの登録例です。

registerBlockVariation() 関数は依存関係配列に指定した wp-blocks から取得し、 __() 関数は wp-i18n から取得します。「themeslug」の文字列部分は適宜変更します。

const { registerBlockVariation } = wp.blocks;
const { __ } = wp.i18n;

// スペーサーブロック(core/spacer)のバリエーションを登録
registerBlockVariation(
  'core/spacer',
  {
    name: 'themeslug/spacer-custom',
    title: __('Spacer Custom', 'themeslug'),
    keywords: ['space', 'spacer', 'spacing', 'スペース', 'スペーサー'],
    attributes: {
      height: '180px',
    },
    // isActive の関数バージョン
    isActive: (blockAttributes) =>
      blockAttributes.height && '180px' === blockAttributes.height,
  }
);

registerBlockVariation() や __() 関数は、以下のように wp.blocks. や wp.i18n. を前に付けて呼び出すこともできます。

wp.blocks.registerBlockVariation(
  'core/spacer',
  {
    name:       'themeslug/spacer-custom',
    title:      wp.i18n.__( 'Spacer Custom', 'themeslug' ),
    keywords:   ['space', 'spacer', 'spacing', 'スペース', 'スペーサー'],
    attributes: {
      height: '180px'
    },
    // isActive の文字列の配列バージョン
    isActive: [ 'height']
  }
);

カスタムバリエーションの作成では、attributes プロパティを使ってデフォルトブロックと区別するために制御する属性を指定します。この例では attributes.height に 180px を指定して、スペーサーブロックの高さを指定しています。

そして、isActive プロパティのコールバック関数で height 属性の値が 180px かどうかを調べることで、現在バリエーションが選択されているかをエディタが判定できるようにします(2つ目の例のように属性の文字列を配列で指定する方法もあり、その方が簡単です)。

name プロパティには「名前空間/スラッグ」を指定していますが、「名前空間」は省略して「スラッグ」のみでも大丈夫です。また、title プロパティは __() 関数を使って多言語対応にしていますが、多言語化が不要であれば、単に文字列を指定します。

上記を保存すると、インサーターに登録したスペーサーブロックのバリエーションが表示されます。title に「Spacer Custom」と指定しているので、そのタイトルが表示されています。

作成したバリエーションのブロックを挿入すると、高さが180pxのスペーサーブロックが挿入されます。

バリエーションをデフォルトにする

プロパティ isDefault: true を追加して、バリエーションをデフォルトにする(元のブロックをバリエーションに置き換える)ことができます。この方法は、コアブロックまたはサードパーティブロックの初期状態を変更する場合に便利です。

以下は前述コードに isDefault: true 追加してバリエーションをデフォルトにする例です。

バリエーションがデフォルトになったため、タイトルを「スペーサー」に変更しています。

wp.blocks.registerBlockVariation(
  'core/spacer',
  {
    name:       'themeslug/spacer-custom',
    title:      wp.i18n.__( 'スペーサー', 'themeslug' ), // タイトルを「スペーサー」に変更
    keywords:   ['space', 'spacer', 'spacing', 'スペース', 'スペーサー'],
    attributes: {
      height: '180px'
    },
    isActive: ( blockAttributes ) =>
      blockAttributes.height && '180px' === blockAttributes.height,
    isDefault: true  // 追加(バリエーションをデフォルトにする)
  }
);

インサータには「スペーサー」が1つだけ表示され、ユーザーの観点からはデフォルトのブロックを使用しているのと変わりません。

isDefault の使用に関する注意

ブロックに既に isDefault に設定された別のバリエーションがある場合は注意が必要です。

エディターは isDefault で最初に登録されたバリエーションを尊重するため、他の isDefault が設定されているバリエーションの登録を解除する必要があります。

参考:Variations / Using isDefault

innerBlocks を使ったバリエーション

innerBlocks プロパティを使用すると、バリエーション内に含めるブロックの配列を指定して、ブロックにコンテンツを追加することができます。

以下はいくつかの attributes プロパティを設定したメディアとテキスト(core/media-text)ブロックのブロックバリエーションの登録例です。

wp.blocks.registerBlockVariation(
  'core/media-text',
  {
    name: 'media-text-custom',
    title: 'メディアとテキスト・カスタム',
    attributes: {
      align: 'wide',
      mediaWidth: 40,
      backgroundColor: 'contrast',
      textColor: 'base'
    },
    isActive: [ 'backgroundColor', 'textColor' ]
  }
);

上記の attributes プロパティでは、core/media-text の align を wide(幅広)に、mediaWidth を 40 に設定して、デフォルトの none(align) と 50(mediaWidth) を上書きしています。

backgroundColor と textColor の値には theme.json で設定されている settings.color.palette の slug を指定しています。16進数やカラーネームでは指定できないようですが、詳細はわかりません。backgroundColor と textColor の使用例としては Variations に掲載されています。

{
  "version": 3,
  "settings": {
    "color": {
      "palette": [
        {
          "color": "#f9f9f9",
          "name": "Base",
          "slug": "base"
        },
        {
          "color": "#111111",
          "name": "Contrast",
          "slug": "contrast"
        }
      ]
    }
  }
}

isActive プロパティには元のブロックにはない属性 backgroundColor と textColor を指定して、元のブロックと区別するようにしています。

デフォルトのメディアとテキストブロックとそのブロックバリエーション(メディアとテキスト・カスタム)をエディタで挿入すると以下のような違いが確認できます。

innerBlocks プロパティ

この例の場合、innerBlocks プロパティを使用してブロックのテキスト部分にデフォルトのコンテンツを追加することができます。

innerBlocks プロパティでは、挿入時にバリエーション内に含めるブロックの配列を指定でき、これらの内部ブロック(インナーブロック)の属性も設定できます。但し、innerBlocks プロパティは、他のブロックを含むブロックに対してのみ機能します。

以下は、前述のバリエーションに innerBlocks プロパティで見出しブロック(core/heading)と段落ブロック(core/paragraph)を追加し、属性で見出しレベルとプレースホルダーを設定する例です。

wp.blocks.registerBlockVariation(
  "core/media-text",
  {
    name: "media-text-custom",
    title: "メディアとテキスト・カスタム",
    attributes: {
      align: "wide",
      mediaWidth: 40,
      backgroundColor: "contrast",
      textColor: "base",
    },
    isActive: [ 'backgroundColor', 'textColor' ],

    // innerBlocks プロパティを追加
    innerBlocks: [
      [
        "core/heading",
        {
          level: 3,
          placeholder: "見出しを入力",
          textColor: "base",
        },
      ],
      [
        "core/paragraph",
        {
          placeholder: "コンテンツを入力"
        },
      ],
    ],
  }
);

エディタで挿入すると、例えば以下のように表示され、見出しと段落ブロックが追加されているのが確認できます。

参考:An introduction to block variations / Creating a variation with inner blocks

isActive プロパティ

isActive プロパティはエディターでバリエーションのインスタンスが選択されたときに、アクティブなバリエーションを確認し、正しいバリエーションのタイトル、アイコン、説明を表示するために使用します。

isActive が設定されていない場合、エディターは元のブロックのインスタンスとバリエーションを区別できないため、元のブロック情報が表示されます。

このプロパティは、文字列の配列または関数で設定できます。但し、Variations には「可能な限り、文字列の配列バージョンを使用することをお勧めします」と書かれています。

文字列の配列バージョンは、ブロックのどの属性(attributes)を比較するかを指定します。各属性がチェックされ、すべてが一致するとバリエーションがアクティブになります。

isActive プロパティがどのように機能するかを確認するために、以下の「テキストとメディア」という新しいブロックバリエーションを作成します。「メディアとテキスト」に似ていますが、attributes プロパティに mediaPosition: 'right' を設定しているので、挿入すると、テキストが左側に、画像が右側に配置されます。

wp.blocks.registerBlockVariation(
  'core/media-text',
  {
    name: 'text-media',
    title: 'テキストとメディア',
    attributes: {
      align: 'wide',
      mediaPosition: 'right'
    }
  }
);

インサーターには元の「メディアとテキスト」と共に「テキストとメディア」が表示されますが、バリエーションを挿入後、ブロックを選択すると、「テキストとメディア」ではなく「メディアとテキスト」というラベルが付いています。

この誤ったラベル付けは、エディターが元の「メディアとテキスト」ブロックとバリエーションとを区別できないために発生します。

この問題を解決するには、isActive プロパティを設定します。

この例の場合、「テキストとメディア」ブロックバリエーションは mediaPosition 属性の定義内容により、区別できるので、以下のように isActive に文字列の配列で [ 'mediaPosition' ] と属性を指定して設定することで、エディタがバリエーションを区別できるようにします。

必要に応じて、align 属性と mediaPosition 属性の両方の定義内容を比較するように isActive に両方の属性の文字列の配列を指定して [ 'align', 'mediaPosition' ] とすることもできます。

wp.blocks.registerBlockVariation(
  'core/media-text',
  {
    name: 'text-media',
    title: 'テキストとメディア',
    attributes: {
      align: 'wide',
      mediaPosition: 'right'
    },
    // isActive プロパティを設定
    isActive: [ 'mediaPosition' ]  // または isActive: [ 'align', 'mediaPosition' ]
  }
);

isActive プロパティを適用すると、エディターは選択したブロックの属性を登録されているバリエーションと比較します。そして、選択したブロックと一致する属性(この場合は mediaPosition の値が right) を持つバリエーションが見つかった場合、エディターはユーザーがそのバリエーションを選択したと認識し、ブロックのラベルはそれに応じて更新されます。

isActive: [ 'align', 'mediaPosition' ] とすれば、両方の属性が一致した場合にアクティブと判定します。

関数バージョン

isActive プロパティの関数バージョンは、ブロックインスタンスの blockAttributes を1番目の引数、バリエーションに対して宣言された variationAttributes を2番目の引数として受け取ります。

これらの引数を使用して、属性の値を比較し、true または false を返すことによって判定します。

前述のコードを関数バージョンで書き換えると以下のようになります(align と mediaPosition の両方を比較しています)。

wp.blocks.registerBlockVariation(
  'core/media-text',
  {
    name: 'text-media',
    title: 'テキストとメディア',
    attributes: {
      align: 'wide',
      mediaPosition: 'right'
    },
    // 関数バージョンの isActive プロパティ
    isActive: ( blockAttributes, variationAttributes ) =>
      blockAttributes.align === variationAttributes.align &&
      blockAttributes.mediaPosition === variationAttributes.mediaPosition
  }
);

参考:Variations / Using isActive

アイコンの追加(icon プロパティ)

icon プロパティを使用してブロックバリエーションに独自のアイコンを割り当てることができます。

簡単なのは Dashicon を使う方法です。使用したいアイコンを選択すると、Dashicon スラッグが表示されるので、dashicons- プレフィックスを削除し、icon プロパティに指定します。

以下は icon プロパティに Dashicon のアイコン(dashicons-align-pull-right)を指定した例です。

Dashicon スラッグの dashicons-align-pull-right から dashicons- を削除した文字列を指定します。

wp.blocks.registerBlockVariation(
  'core/media-text',
  {
    name: 'text-media',
    title: 'テキストとメディア',
    attributes: {
      align: 'wide',
      mediaPosition: 'right'
    },
    isActive: [ 'align', 'mediaPosition' ],
    // icon プロパティを追加
    icon: 'align-pull-right'
  }
);

例えば、以下のように表示されます。

カスタム SVG アイコンを追加

Dashicon に適当なアイコンがない場合は、独自の SVG アイコンを作成して追加することもできます(カスタム SVG アイコンは通常、24 x 24ピクセルで表示されます)。

例えば、以下のような SVG を作成した場合、

以下は上記アイコンのインライン SVG です。

<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 240 240">
  <path d="M127.542,57.624h98.916V181.376H127.542V57.624ZM29.718,67.894H104.43V84.106H29.718V67.894Zm0,44H104.43v16.212H29.718V111.894Zm0,43H104.43v16.212H29.718V154.894Z"/>
</svg>

プレーンな JavaScript を使用してカスタム SVG を追加するには、WordPress の組み込みコンポーネントと関数を利用します。

まず、functions.php の block-variations.js(ブロックバリエーションを記述するファイル)の読み込みの wp_enqueue_script() で、wp-element と wp-primitives を依存関係の配列に追加します。

add_action('enqueue_block_editor_assets', 'themeslug_enqueue_block_variations');

function themeslug_enqueue_block_variations() {
  wp_enqueue_script(
    'themeslug-block-variations',
    get_theme_file_uri('assets/js/block-variations.js'),
    array(
      'wp-blocks',
      'wp-dom-ready',
      'wp-i18n' ,
      // 以下を追加
      'wp-element',
      'wp-primitives'

    ),
    wp_get_theme()->get('Version'),
    false
  );
}

そして、wp.element.createElement()、wp.primitives.SVG、wp.primitives.Path を使用してアイコンオブジェクトを作成します。

7行目の d: には SVG の path 要素の d 属性の値を指定します(インライン SVG の2行目の値)。

const textMediaIcon = wp.element.createElement(
  wp.primitives.SVG,
  { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 240 240" },
  wp.element.createElement(
    wp.primitives.Path,
    {
      d: "M127.542,57.624h98.916V181.376H127.542V57.624ZM29.718,67.894H104.43V84.106H29.718V67.894Zm0,44H104.43v16.212H29.718V111.894Zm0,43H104.43v16.212H29.718V154.894Z",
    }
  )
);

そして、icon プロパティに作成したアイコンオブジェクト textMediaIcon を指定します。

wp.blocks.registerBlockVariation(
  'core/media-text',
  {
    name: 'text-media',
    title: 'テキストとメディア',
    attributes: {
      align: 'wide',
      mediaPosition: 'right'
    },
    isActive: [ 'align', 'mediaPosition' ],
    // アイコンオブジェクトを指定
    icon: textMediaIcon,
  }
);

これで、例えば以下のように独自のアイコンを表示することができます。

参考ページ:Adding custom icons(An introduction to block variations)

Photoshop での SVG アイコンの作成

ブロックバリエーションとは直接関係ありませんが、Photoshop で SVG アイコンを作成した際のごく個人的な覚書です。

新しい、Photoshop では SVG の書き出しがデフォルトではなくなってしまっています。

SVG の書き出しをできるようにするには、環境設定の「書き出し」でオプションの「従来の書き出し形式を使用」にチェックを入れる必要があります。

SVG の書き出しでは、それぞれのレイヤーが別々のままの場合、

例えば、以下のように別々の path 要素で書き出されてしまうので、d 属性の値を手動で編集しなければなりませんが、

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 240 240">
  <defs>
    <style>
      .cls-1 {
        stroke: #000;
        stroke-width: 1.253px;
        fill-rule: evenodd;
      }
    </style>
  </defs>
  <path id="長方形_右" data-name="長方形 右" class="cls-1" d="M127.542,57.624h98.916V181.376H127.542V57.624Z"/>
  <path id="長方形_左_" data-name="長方形 左3" class="cls-1" d="M29.718,67.894H104.43V84.106H29.718V67.894Z"/>
  <path id="長方形_左_2" data-name="長方形 左2" class="cls-1" d="M29.718,111.894H104.43v16.212H29.718V111.894Z"/>
  <path id="長方形_左_3" data-name="長方形 左1" class="cls-1" d="M29.718,154.894H104.43v16.212H29.718V154.894Z"/>
</svg>

全てのレイヤーを選択して、右クリックから「シェイプを結合」を適用してから、

SVG に書き出すと、以下のように1つの path 要素にまとめられます。

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 240 240">
  <defs>
    <style>
      .cls-1 {
        stroke: #000;
        stroke-width: 1.253px;
        fill-rule: evenodd;
      }
    </style>
  </defs>
  <path id="長方形_左_" data-name="長方形 左1" class="cls-1" d="M127.542,57.624h98.916V181.376H127.542V57.624ZM29.718,67.894H104.43V84.106H29.718V67.894Zm0,44H104.43v16.212H29.718V111.894Zm0,43H104.43v16.212H29.718V154.894Z"/>
</svg>

ブロックバリエーションの登録解除

ブロックバリエーションの登録を解除するには、unregisterBlockVariation() 関数を使用します。

unregisterBlockVariation( blockName, variationName ) 

この関数は以下の2つのパラメータを受け取ります。

パラメータ 説明
blockName 登録解除するバリエーションの元のブロックの名前 (名前空間を含む)。
variationName 登録解除するバリエーションの名前。

例えば、前項で作成したスペーサーブロックのバリエーションの登録を解除したい場合は、以下を block-variations.js に記述します。

// wp.domReady を使用して登録を解除します
wp.domReady( () => {
  wp.blocks.unregisterBlockVariation(
    'core/spacer',
    'themeslug/spacer-custom'
  );
} );

※ ブロックを登録解除するときは、wp.domReady を使用する必要があります。これがないと、関数が早く実行されてしまい、バリエーションが削除されません。