wordpressのビジュアルモードにcssを適用する方法

wordpressの固定ページでフロント向けのcssを記述しても、管理画面上ではcssが効きません。なので、管理画面用のcssを記述すれば、なんとかなるかなと思ったのですが、これがうまくいきません。なぜならば、その領域はiframeで構成されているためでした。iframe内のコードに対して外からはcssを当てられないのです。

iframeの外であればfunction.phpに以下のような記述を加えれば、反映します。

function my_admin_style(){
  wp_enqueue_style( 'my_admin_style', get_template_directory_uri().'/admin.css' );
  ///テンプレート内のadmin.cssを管理画面にいる時に読む込みます。
}
add_action( 'admin_enqueue_scripts', 'my_admin_style' );

しかし、これでは問題は解決しません。これを解決するにはjavascriptでiframe内のDOMを読み出して、そこに対して、.styleプロパティを利用してcssを反映させます。

まずは次のコードをfunction.phpに追加し、admin.jsを管理画面で表示するようにします。

function theme_name_scripts() {
  wp_enqueue_script('custom_js', get_template_directory_uri() . '/admin.js');
  //テンプレート内のadmin.jsを管理画面にいる時に読む込みます。
}
add_action( 'admin_enqueue_scripts', 'theme_name_scripts' );

そのうえで、admin.jsは以下のように記述します。

window.onload = function(){
  const content_ifr = document.getElementById('content_ifr');
  const spanBlocks = content_ifr.contentWindow.document.getElementsByClassName("span_block");
  for(i=0;i<spanBlocks.length;i++){
    spanBlocks[i].style.display = "block";
  }
}

解説します。windows.onloadはページ内のhtmlの読み込みが完了するのを待つコードです。これがないと、エラーが出てしまいます。

次にgetElementByIdでiframeをidで指定しcontent_ifrへ代入します。更には
content_ifr.contentWindow.document.getElementsByClassName(“span_block”)
でクラス名にspan_blockが指定されているDOMをすべて読み込み、spanBlocksへ配列として代入しています。

最後に配列内の要素を順次、.styleプロパティで変更しています。ここではdisplay:blockにすることで<span class=”span_block”>○○○○○</span>をインライン要素からブロック要素にしています。

フロント向けのcssでは以下のようにspan_blockクラスはブロック要素になるよう記述しています。

.span_block{
		display:block
}

このような対策をとったのは、ビジュアルエディター内の改行がフロント側で<br>に変換しまい、改行位置の整合性が撮れなかったためです。応用すれば、ここだけはフロント同じ見せ方をしたい、という時に便利だと思います。