【原因&解決】WordPressでadd_editor_style()が効かない・反映されない(絶対パスだと動かない・URLだとサーバによって動いたり動かなかったり・@importを使うと反映されない)

いつも忘れるので備忘録としてメモ。結論だけ先に書くと「editor-style.cssはテーマフォルダからの相対パスを指定する必要がある」「editor-style.css内では@importの書き方に注意」です。以下解説。

add_editor_styleの使いどころ。

開発者がブロックエディタなどに独自のCSSを追加する機能。多くの場合、テーマフォルダ内の functions.php (function ではなく functions だ!)に after_setup_theme フックを使って追加します。

僕の場合は、ブロックエディタのブロックに薄く枠線を付けたり、Bootstrapやサイトのフロントエンド用のCSSがエディタにも反映される目的で使っています。Wordなんかで編集記号を表示させる感覚に近いかも。

例えばこんなeditor-styleを読み込ませます。

.pc,
div.pc,
span.pc,
br.pc {
	border: 1px dashed hsl(0, 100%, 50%);
}
.pc:before {
	content: "PC表示";
	color: hsl(0, 100%, 50%);
	display: block;
	font-size: 85%;
	position: absolute;
	top: 0.1em;
	left: 0.1em;
	font-weight: bold;
	z-index: 1000;
}
.sm,
div.sm,
span.sm,
br.sm {
	border: 1px dashed hsl(210, 100%, 50%);
}
.sm:before {
	content: "Mobile表示";
	color: hsl(210, 100%, 50%);
	display: block;
	font-size: 85%;
	position: absolute;
	top: 0.1em;
	left: 0.1em;
	font-weight: bold;
	z-index: 1000;
}
.is-root-container {
	margin: 2px auto;
	padding: 1rem;
	width: 768px;
	border: 1px solid #ccc;
	background-color: #fff;
}
.wp-block {
	border: 1px dashed #eee;
}
.wp-block-group {
	padding: 4px;
	border: 1px dotted #ccc;
}
.wp-block-group:after {
	content: "グループ(flexレイアウト)";
	display: block;
	font-size: 50%;
	color: #999;
	position: absolute;
	top: 0;
	right: 0;
}
.wp-block-columns,
.wp-block-column {
	padding: 4px;
	border: 1px dotted #ccc;
}
.wp-block-columns:after,
.wp-block-column:after {
	display: block;
	font-size: 50%;
	color: #999;
	position: absolute;
	top: 0;
	right: 0;
}
.wp-block-columns:after {
	content: "カラム枠";
}
.wp-block-column:after {
	content: "カラム";
}
.block-library-block__reusable-block-container {
	padding: 4px 0 !important;
	border: 1px dotted #f88;
}
.block-library-block__reusable-block-container:after {
	content: "再利用ブロック(編集すると他の部分も更新されます。)";
	display: block;
	font-size: 50%;
	color: #c66;
	position: absolute;
	top: 0;
	right: 0;
}

動いたり動かなかったりした書き方

URLを書けばいいっしょ!って事でこんな書き方をした。この場合、テストのサーバでは動くのに、本番のレンタルサーバでは動かない(泣)

// functions.php:動かない!(ときどき動く?Why?)
add_action('after_setup_theme', function () {
	add_theme_support('editor-styles');
	add_editor_style('https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css');
	add_editor_style(get_template_directory_uri() . 'css/editor-style.css');
});

add_editor_styleの挙動と動かない原因

とりま、結論を急ぐならこの章は読み飛ばしてもOK。

まず、エディタ用のCSSは add_editor_style() 関数によってグローバル変数「 $editor_styles」に追加される。(/wp-includes/theme.php : add_editor_style() 関数)

んで、いろいろフィルタがあったりして、最終的に:

  • CSSがhttp・httpsで始まる場合 → wp_remote_get() 関数でCSSの内容を読み込む
  • それ以外の場合には get_theme_file_path() 関数で取得したテーマフォルダへのパスを結合して file_get_contents() 関数で内容を読み込む

(/wp-includes/block-editor.php : get_block_editor_theme_styles() 関数)

で、CSSを読み込んだら、エディタにはCSSファイルをタグで挿入するのではなくて、エディタのインラインフレームのソースコードに直書きしてCSSを反映させる

なので、こういう現象が起こっています:

  • エディタ用のCSSをURLで指定した場合、PHPの実行時設定で外部URLを取ってこれないようにしていた場合は内容を読み込めない。
  • 絶対パスで指定した場合、テーマフォルダへのパスが結合されるので全然違う場所を読み込みに行って、見つからない。
  • editor-style.css内に@importが使われていて、かつurlが相対パスで指定されている場合は、想定された場所のCSSを読みに行けないので反映されない。

結論:動く書き方

じゃあ、動くようにするためにはどう書けばいいかと言うと、「テーマディレクトリからの先頭の / 無し相対パス」で指定すると動く。あと、@importはややこしいので使わないほうが良い…という結論になる。

例えばこんな感じ。

// functions.php:動く!
add_action('after_setup_theme', function () {
	add_theme_support('editor-styles');
	add_editor_style('css/bootstrap.min.css'); // bootstrapをローカルに設置して、テーマディレクトリからの相対パスで記述
	add_editor_style('css/style.css'); // テーマディレクトリからの相対パスで記述
	add_editor_style('css/editor-style.css'); // テーマディレクトリからの相対パスで記述
});

感想

そういう大事なことはヘルプファイルや公式ドキュメントに目立つように書いておいて欲しいです…(´・ω・`)

ちなみに、画像はAIが考える「Webサイトスタイリスト」です。そんな職業あるのかなあ。知らんけど。

質問・コメントなどあると嬉しいです