2026年7月18日

2026年7月18日

WordPressのwp_enqueue_style()とwp_add_inline_style()でCSS変数を:rootに注入する方法

カスタマイザーの設定値や投稿ごとの値を CSS 変数(カスタムプロパティ)として :root に出力したいときは、wp_enqueue_style() で読み込んだスタイルシートに wp_add_inline_style() で :root{--変数名:値} を追加するのが WordPress の正しい手順です。wp_head に <style> を直接 echo するより、読み込み順の管理や他のプラグインとの共存がしやすくなります。この記事では、基本の書き方、値のサニタイズ、スタイルシートが無い場合の扱い、カスタマイザーのライブプレビュー、ブロックテーマとの使い分け、確認方法までを説明します。

仕組み:インラインCSSはハンドルにひも付く

wp_add_inline_style( $handle, $data ) は、指定したハンドルのスタイルシートの直後に <style> を出力する関数です。出力される要素には id="{ハンドル名}-inline-css" が付きます。ひも付け先のハンドルがキューに入っていないと何も出力されないため、先に wp_enqueue_style()(または wp_register_style() と wp_enqueue_style())を済ませておくことが前提です。

この方式の利点は3つあります。

  • 変数の定義が、変数を使うスタイルシートの直後に出るので、読み込み順が明確になる
  • 依存関係の仕組みに乗るため、そのスタイルシートが読み込まれないページでは変数も出ない
  • 他のプラグインが同じハンドルに追記したり、wp_dequeue_style() で外したりできる

$data には <style> タグを含めず、CSS の中身だけを渡します。タグを含めると二重になって表示が崩れます。

基本の書き方

コードは子テーマの functions.php に書きます。親テーマに直接書くと、テーマの更新で消えてしまいます。作業前にはサイトのバックアップを取り、可能ならステージング環境で試してから本番に反映してください。

次の例は、カスタマイザーに保存したアクセントカラーと角丸の大きさを、CSS 変数として出力するものです。

add_action( 'wp_enqueue_scripts', function () {
	$path = get_stylesheet_directory() . '/assets/main.css';

	wp_enqueue_style(
		'mytheme-main',
		get_stylesheet_directory_uri() . '/assets/main.css',
		array(),
		file_exists( $path ) ? (string) filemtime( $path ) : null
	);

	$accent = sanitize_hex_color( get_theme_mod( 'mytheme_accent', '#1e73be' ) );
	if ( ! $accent ) {
		$accent = '#1e73be';
	}
	$radius = min( 40, absint( get_theme_mod( 'mytheme_radius', 8 ) ) );

	$css = sprintf(
		':root{--mytheme-accent:%1$s;--mytheme-radius:%2$dpx;}',
		$accent,
		$radius
	);

	wp_add_inline_style( 'mytheme-main', $css );
} );

スタイルシート側では、変数を var() で参照します。第2引数に初期値を書いておくと、何らかの理由で変数が出力されなかったときも表示が崩れません。

.mytheme-button {
	background-color: var(--mytheme-accent, #1e73be);
	border-radius: var(--mytheme-radius, 8px);
}

バージョン引数に filemtime() を使っているのは、CSS ファイルを更新したときにブラウザに古いファイルを使わせないためです。インライン CSS の部分は毎回 HTML に含まれるので、キャッシュの心配はありません。

値は出力前に型をそろえる

CSS 変数の値は HTML の <style> の中にそのまま出力されます。WordPress のコアには CSS の文脈専用のエスケープ関数がないため、「その変数に入ってよい形」だけを通す考え方で守ります。

  • 色:sanitize_hex_color() で #RRGGBB などの形式だけを通す。不正な値なら初期値に戻す
  • 数値:absint() や (float) で数値にし、min() / max() で範囲を制限する。単位はコード側で付ける
  • 選択肢:フォント名やレイアウト名などは、許可する値の配列を用意して in_array( $value, $allowed, true ) で照合する

自由入力の文字列をそのまま CSS に入れるのは避けてください。} や </style> を含む値が入ると、以降の CSS が壊れたり、HTML の構造を書き換えられたりする恐れがあります。カスタマイザーに設定を登録するときも、sanitize_callback を指定して保存時点で値を整えておくと二重の守りになります。

add_action( 'customize_register', function ( $wp_customize ) {
	$wp_customize->add_setting( 'mytheme_accent', array(
		'default'           => '#1e73be',
		'sanitize_callback' => 'sanitize_hex_color',
		'transport'         => 'postMessage',
	) );

	$wp_customize->add_control( new WP_Customize_Color_Control(
		$wp_customize,
		'mytheme_accent',
		array(
			'label'   => 'アクセントカラー',
			'section' => 'colors',
		)
	) );
} );

ひも付けるスタイルシートが無い場合

変数だけを出したくて、ひも付ける CSS ファイルが無い場合は、src に false を渡したハンドルを登録すると、インライン CSS だけを出力できます。

add_action( 'wp_enqueue_scripts', function () {
	wp_register_style( 'mytheme-vars', false, array(), null );
	wp_enqueue_style( 'mytheme-vars' );
	wp_add_inline_style( 'mytheme-vars', ':root{--mytheme-gap:1.5rem;}' );
} );

この場合、変数を使う他のスタイルシートの依存関係に mytheme-vars を入れておくと、変数の定義が先に出力されます。

投稿ごとに値を変える

投稿や固定ページごとに色を変えたい場合は、wp_enqueue_scripts の中で is_singular() を確認し、カスタムフィールドの値を読み出します。

add_action( 'wp_enqueue_scripts', function () {
	if ( ! is_singular() ) {
		return;
	}
	$color = sanitize_hex_color( get_post_meta( get_queried_object_id(), 'mytheme_page_accent', true ) );
	if ( $color ) {
		wp_add_inline_style( 'mytheme-main', ':root{--mytheme-accent:' . $color . ';}' );
	}
}, 20 );

優先度を 20 にしているのは、先ほどの mytheme-main の読み込み(優先度 10)より後に実行するためです。同じハンドルへの追記は、追加した順に出力されます。同じ詳細度の :root が後から出るので、投稿ごとの値がサイト全体の値を上書きします。

カスタマイザーで即時プレビューする

カスタマイザーの設定で transport を postMessage にした場合は、プレビュー画面用のスクリプトで CSS 変数を書き換えると、ページを再読み込みせずに色の変化を確認できます。

add_action( 'customize_preview_init', function () {
	wp_enqueue_script(
		'mytheme-customizer-preview',
		get_stylesheet_directory_uri() . '/assets/customizer-preview.js',
		array( 'customize-preview' ),
		'1.0.0',
		true
	);
} );
( function ( api ) {
	api( 'mytheme_accent', function ( value ) {
		value.bind( function ( to ) {
			document.documentElement.style.setProperty( '--mytheme-accent', to );
		} );
	} );
} )( wp.customize );

document.documentElement は <html> 要素で、:root と同じ要素を指します。

ブロックテーマとの使い分け

ブロックテーマ(theme.json を持つテーマ)では、theme.json の settings.color.palette に登録した色が --wp--preset--color--{slug} という CSS 変数として自動的に出力されます。settings.custom に書いた値も --wp--custom--{キー} として出力されます。固定の配色やサイズは theme.json で定義し、ユーザーがサイトエディターのスタイルから変更する仕組みに任せるのが基本です。

wp_add_inline_style() が向いているのは、theme.json で表せない動的な値です。たとえば、独自の設定画面の値、投稿ごとのメタデータ、ログイン状態で変わる値などです。なお、ブロックテーマでは管理画面のメニューにカスタマイザーが表示されないことがあります。設定の置き場所は、テーマの種類に合わせて選んでください。

ブロックエディターの編集画面にも同じ変数を効かせたい場合は、enqueue_block_assets フックで読み込むと、エディターの iframe 内とフロントの両方に出力されます。どの画面で読み込まれるかは WordPress のバージョンで変わってきた経緯があるため(2026年10月現在)、エディター上での見た目は実際に開いて確認してください。

表示のずれ(CLS)を防ぐ

CSS 変数の定義は、<head> 内で変数を使うスタイルシートと一緒に出力されるのが理想です。wp_enqueue_scripts でスタイルをキューに入れれば <head> に出力されます。JavaScript で後から setProperty() するだけの実装にすると、初回表示では初期値で描画され、その後に色や余白が切り替わるため、ちらつきやレイアウトのずれ(CLS)の原因になります。

出力の確認方法

  1. ページのソースを表示し、id="mytheme-main-inline-css" の <style> が mytheme-main の <link> の直後にあるか確認する
  2. 開発者ツールで <html> 要素を選び、「計算済み」またはスタイルの一覧に --mytheme-accent が表示されるか見る
  3. 値が反映されない場合は、変数名のつづり(大文字と小文字は区別されます)、var() 側の名前、より詳細度の高いセレクターでの上書きを確認する
  4. キャッシュプラグインや CSS の結合・最適化機能を使っている場合は、キャッシュを削除してから再確認する

まとめ

  • CSS 変数は wp_enqueue_style() で読み込んだハンドルに wp_add_inline_style() で :root{...} を追加して出力する
  • 値は sanitize_hex_color()、absint()、許可リストで型をそろえてから出力し、自由入力の文字列は入れない
  • ひも付ける CSS が無いときは src に false を渡したハンドルを使い、投稿ごとの値は後の優先度で追記する
  • ブロックテーマでは固定値を theme.json に任せ、動的な値だけを wp_add_inline_style() で補う
  • 変数は <head> で出力し、ソースと開発者ツールで出力位置と値を確認する

お気軽にご相談ください

お見積りへ お問い合わせへ
▲