テーマのスタイルをブロックごとのCSSに付加して読み込む - WordPress 5.8

「should_load_separate_core_block_assets」を有効化すると、ページ内で使用したブロックのCSSのみを読み込むようになります。

前回の記事を書いた時点では「should_load_separate_core_block_assets」が作用するのは「コアブロックのCSSのみ」かと思っていましたが、プラグインで追加したブロックでも作用するものがありました。

Snow Monkey Blocks」です。
https://ja.wordpress.org/plugins/snow-monkey-blocks/

国産のGutenberg対応テーマ「Snow Monkey」に最適化されたブロック集ですが、どんなテーマでも使うことができます。

たとえば、Snow Monkey Blocksの「アラート」ブロックを使用し、「should_load_separate_core_block_assets」を有効化してみると、次のように外部CSSの形でアラートブロックのCSSのみが読み込まれるようになります。

<link rel="stylesheet" id="snow-monkey-blocks/alert-css" href="…/plugins/snow-monkey-blocks/dist/block/alert/style.css?ver=1626331159" media="all">
<style id="wp-block-image-inline-css">…</style>
<style id="global-styles-inline-css">…</style>
</body>
</html>

こうしたブロック集をたくさん追加しはじめると、CSSもたくさん読み込まれるようになるのが常でしたので、「should_load_separate_core_block_assets」に対応したブロックの存在はありがたいです。

ただ、テーマのスタイルの優先度が低くなるという問題はどのブロックを使った場合でも同じです。そのため、問題を回避する方法を見ていきます。

テーマのスタイルをブロックに適用する方法

テーマのスタイルをブロックに適用する方法としては、

  1. テーマのCSSファイル(style.cssなど)にスタイルの設定を記述し、
    エディタの「高度な設定」でクラス名を指定して適用する方法

または

  1. register_block_style()でスタイルを登録し、
    エディタの「スタイル」で選択して適用する方法

がありますが、どちらの方法で適用した場合でも優先度の問題が発生します。

このうち、1. のスタイルに関してはブロックのCSSに付加して読み込み、問題を回避するコード例が Make WordPress Core の記事に掲載されています。

「Block-styles loading enhancements in WordPress 5.8」
https://make.wordpress.org/core/2021/07/01/block-styles-loading-enhancements-in-wordpress-5-8/

2. のスタイルに関しては、WordPress5.8ではブロックのCSSに付加されません。
次のようなticketが作成されていますので、WordPress 5.9では付加されるようになりそうですが、当面は優先度の問題が残りますので注意が必要です。

Registered block styles should only be rendered when the block exists on a page
https://core.trac.wordpress.org/ticket/53616

というわけで、1. の優先度の問題を回避できる Make WordPress Core のコード例を試してみました。

テーマのCSSファイルに記述したスタイル

まずは、テーマのCSSファイルに記述したスタイルを用意します。

ここでは、『WordPressレッスンブック 5.x対応版』で作成した「カラム」ブロックのレスポンシブをアレンジするスタイルを使います。画面幅に合わせて3→2→1列と変化するカラムブロックを、3→1列と変化させるようにするスタイルで、style.cssに記述してあります。

カラムブロックのレスポンシブをアレンジするテーマのCSS(ブロックスタイル)

style.cssに記述したカラムブロックをアレンジするスタイル D′

/* カラムブロックのレスポンシブ(P.300) */
@media (min-width: 600px) and (max-width: 781px) {
.myresp {
flex-wrap: nowrap;
}
.myresp > *:not(:first-child) {
margin-left: 10px;
}
}

標準では次の順に読み込まれるため、D′ は優先度が高く、GutenbergのカラムブロックのCSS B′ を上書きできます。

標準の読み込み順

しかし、「should_load_separate_core_block_assets」を有効化すると読み込み順が変わり、上書きできなくなります。

「should_load_separate_core_block_assets」を有効化したときの読み込み順

ブロックのCSSに付加して読み込む

Make WordPress Core のコード例を使用して D′B′ に付加し、上書きできるようにします。

functions.php にコード例をコピーし、 D′ を付加したいブロックを $styled_blocks = [~] で指定します。ここでは「columns(カラムブロック)」と指定しています。

/**
* Attach extra styles to multiple blocks.
*/
function my_theme_enqueue_block_styles() {
// An array of blocks.
$styled_blocks = [ 'columns' ];
foreach ( $styled_blocks as $block_name ) {
// Get the stylesheet handle. This is backwards-compatible and checks the
// availability of the `wp_should_load_separate_core_block_assets` function,
// and whether we want to load separate styles per-block or not.
$handle = (
function_exists( 'wp_should_load_separate_core_block_assets' ) &&
wp_should_load_separate_core_block_assets()
) ? "wp-block-$block_name" : 'wp-block-library';
// Get the styles.
$styles = file_get_contents( get_theme_file_path( "styles/blocks/$block_name.min.css" ) );
// Add frontend styles.
wp_add_inline_style( $handle, $styles );
// Add editor styles.
add_editor_style( "styles/blocks/$block_name.min.css" );
if ( file_exists( get_theme_file_path( "styles/blocks/$block_name-editor.min.css" ) ) ) {
add_editor_style( "styles/blocks/$block_name-editor.min.css" );
}
}
}
// Add frontend styles.
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_block_styles' );
// Add editor styles.
add_action( 'admin_init', 'my_theme_enqueue_block_styles' );

※コアブロック以外にも対応させるには、修正の必要があります。

続けて、style.cssに記述していた D′ を取り出し、カラムブロック用のCSSファイルに移して保存します。パスやファイル名はコード例の設定に従って指定しています(わかりやすいようにCSSはminifyしていません)。

styles/blocks/columns.min.css に移した D′

/* カラムブロックのレスポンシブ(P.300) */
@media (min-width: 600px) and (max-width: 781px) {
.myresp {
flex-wrap: nowrap;
}
.myresp > *:not(:first-child) {
margin-left: 10px;
}
}

以上で、設定完了です。これで、D′B′ に付加して読み込まれるようになります。

「should_load_separate_core_block_assets」を有効化&コード例を使用したときの読み込み順

フロントに出力された B′D′

<style id="wp-block-columns-inline-css">
.wp-block-columns{display:flex;margin-bottom:1.75em;box-sizing:
… .wp-block-column.is-vertically-aligned-top{width:100%}
/* カラムブロックのレスポンシブ(P.300) */
@media (min-width: 600px) and (max-width: 781px) {
.myresp {
flex-wrap: nowrap;
}
.myresp > *:not(:first-child) {
margin-left: 10px;
}
}
</style>
<style id="wp-block-image-inline-css">…</style>
<style id="global-styles-inline-css">…</style>
</body>
</html>

なお、コード例を使った設定では、D′ はエディタにも適用されます。
また、「should_load_separate_core_block_assets」を無効化した場合、B′ が含まれる B は外部CSSとして読み込まれるため、D′B に続けてインラインで読み込まれます。

「should_load_separate_core_block_assets」を無効化&コード例を使用したときの読み込み順

ブロックごとにCSSファイルを用意するのは面倒な気もしましたが、ブロックスタイルが増えてくるとCSSがカオスになりがちなので、すっきりと管理できていいかもしれません。