ブロックエディタにテーマ独自のクラスを利用したスタイルを適用する

2020-07-11
2020-07-11

ブロックエディタの表示にテーマのCSSを当てると、コンテンツエリアは完全なWYSIWYGに近くなり、いちいちプレビューしないでもイメージ通りに編集していくことができる。
そのためにはafter_setup_themeフックでeditor-stylesをサポートして、エディタに適用するCSSをadd_editor_styleすればよい。

ブロックエディタを利用したときのHTML構造やクラスに配慮したCSSであれば以下の手順でだいたいOK。

functions.php

function setup_theme_editor_style()
{
    add_theme_support('editor-styles');
    add_editor_style('assets/css/main.css');
}
add_action('after_setup_theme', 'setup_theme_editor_style');

add_editor_styleの引数はテーマディレクトリからの相対パス。

参考

Qiita

Gutenbergのブロックエディターにテーマのスタイルを適用する方法 - Qiita

https://qiita.com/youthkee/items/3c8b8f91314727d40d3f

独自のクラスを使っている場合にうまくいかない

しかし上記のやり方だけではラッパーに独自クラスを使っている場合などにうまくいかない。
例えば以下のように、pタグに直接スタイルを当てず、独自クラスを持ったラッパー以下のpタグにのみスタイルを当てている場合など。

<style>
.article__content p {
  margin-top: 15px;
  color: #444;
}
</style>

<div class="article__content">
  <?php the_content() ?>
</div>

ブロックエディタではarticle__contentというクラスが当たってないのでCSSの内容は表示に反映されないと言う理屈だ。

ブロックエディタのブロックに独自のクラスを追加する

これを解決するにはブロックフィルターを使ってブロックにarticle__contentというクラスを当ててやればいい。

やり方としてはまず追加のJSを読み込むためのenqueue_block_editor_assetsフックを使う。

そしてそのJSでBlockListBlockブロックフィルターを使ってブロックエディターの編集ブロックにスタイルを追加する。

functions.php

add_action('enqueue_block_editor_assets', function() {
	wp_enqueue_script( 'editor-helper', get_template_directory_uri() . '/assets/js/editor-helper.js', array('wp-blocks'));
});

editor-helper.js

var el = wp.element.createElement;
 
var withClientIdClassName = wp.compose.createHigherOrderComponent( function( BlockListBlock ) {
    return function( props ) {
        var newProps = lodash.assign(
            {},
            props,
            {
                className: "article__content",
            }
        );
 
        return el(
            BlockListBlock,
            newProps
        );
    };
}, 'withClientIdClassName' );
 
wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-name', withClientIdClassName );

Block Editor HandbookのBlock Filtersからコピペして修正したもの。

HTML構造の注意点

エディタのレンダリング結果は以下のようなHTML構造となる。

<div class="article__content">
  <p>段落1</p>
</div>

<div class="article__content">
  <p>段落2</p>
</div>

ラッパーにマージンなどを指定していると表示が意図したとおりにならないので注意。

こういうのを見ると最初からWordPress Wayに沿ったCSSを書いた方がいいように思える。

おまけ p:firstの罠

ブロックエディタ上では全ての段落がp:firstに該当してしまうので、それを使っているとレイアウトが崩れるという罠がある。
公開したコンテンツとブロックエディタの表示を完全に一致させようとするのに邪魔になるので、使わない方がいいようだ。

Profile

フルスタック気味のフリーランスプログラマー。

どちらかと言うと得意はインフラ構築とサーバーサイドプログラミングですが、フロントエンドもぼちぼちやっています。

最近の興味範囲はWordPress、AWS、サーバーレス、UIデザイン。

愛車はセロー。カメラはペンタックス。旅好きです。横浜在住。