2026年5月20日

2026年5月20日

WordPressテーマでSCSSを使う方法(Dart Sassのコンパイルと読み込み)

SCSS は、変数・ネスト・ミックスインなどを使って CSS を書ける言語です。ブラウザは SCSS をそのまま読めないため、Sass で CSS にコンパイルし、できた CSS ファイルを WordPress で読み込みます。

この記事では、Sass の公式実装である Dart Sass(npm パッケージ名 sass)を使います。Node.js が必要です。

全体の流れ

  1. テーマのフォルダーに scss/ を作り、SCSS を書く
  2. sass でコンパイルし、assets/css/main.css に出力する
  3. functions.php で assets/css/main.css を読み込む

テーマの style.css は、先頭のコメント(Theme Name: など)を WordPress がテーマ情報として読むファイルです。コンパイル結果で上書きすると、圧縮の設定によってはコメントが消え、テーマとして認識されなくなります。そのため、コンパイル結果は別のファイルに出力し、style.css はテーマ情報だけのファイルとして残す方法が扱いやすくなります。

Sass を入れる

# テーマのフォルダーで実行
cd wp-content/themes/my-theme
npm init -y
npm install --save-dev sass

# 入ったバージョンを確認
npx sass --version

package.json の scripts に、コンパイルのコマンドを追加します。

{
  "scripts": {
    "sass:watch": "sass scss/main.scss assets/css/main.css --watch",
    "sass:build": "sass scss/main.scss assets/css/main.css --style=compressed --no-source-map"
  }
}
# 開発中: SCSS を保存するたびにコンパイルする(Ctrl+C で止める)
npm run sass:watch

# 公開用: 圧縮して出力する
npm run sass:build

--watch では、既定でソースマップ(main.css.map)も出力され、ブラウザの開発ツールで SCSS の行番号を確認できます。公開用では --no-source-map で出力しないようにしています。

ファイルを分けて書く(@use)

ファイルが大きくなったら、役割ごとに分けます。名前が _ で始まるファイル(パーシャル)は、単独では CSS に出力されず、ほかのファイルから読み込まれるだけになります。

my-theme/
├── style.css            テーマ情報だけ
├── functions.php
├── assets/css/main.css  コンパイル結果(自動で作られる)
└── scss/
    ├── main.scss        入口のファイル
    ├── _variables.scss
    ├── _mixins.scss
    ├── _base.scss
    └── _card.scss

入口の main.scss で、各パーシャルを @use で読み込みます。拡張子と先頭の _ は省けます。

// scss/main.scss
@use 'base';
@use 'card';

変数とミックスインを定義します。

// scss/_variables.scss
$color-primary: #2271b1;
$color-text: #1d2327;
$space-md: 1.5rem;
$radius: 6px;

// SCSS の変数を CSS カスタムプロパティとしても出力する
:root {
  --color-primary: #{$color-primary};
  --space-md: #{$space-md};
}
// scss/_mixins.scss
@mixin respond-to($breakpoint) {
  @if $breakpoint == sm {
    @media (max-width: 600px) { @content; }
  } @else if $breakpoint == md {
    @media (max-width: 900px) { @content; }
  } @else {
    @error "未対応のブレークポイント: #{$breakpoint}";
  }
}

@use で読み込んだ変数やミックスインは、読み込んだファイルの中でしか使えません。使うファイルごとに @use します。as * を付けると、variables.$radius のような名前空間なしで使えます。

// scss/_base.scss
@use 'variables' as *;

body {
  color: $color-text;
}
// scss/_card.scss
@use 'variables' as *;
@use 'mixins';

.card {
  border-radius: $radius;
  overflow: hidden;

  &__body {
    padding: $space-md;
  }

  &:hover {
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  }

  @include mixins.respond-to(sm) {
    border-radius: 0;
  }
}

_variables.scss の :root { … } は、_base.scss と _card.scss の両方から @use されていますが、CSS には1回だけ出力されます。@use は同じファイルを何度読み込んでも1回しか評価しないためです。

&__body は .card__body、&:hover は .card:hover にコンパイルされます。

@import は非推奨

古い記事では @import 'variables'; でファイルを読み込む例が多く見られますが、Sass の @import は Dart Sass 1.80.0 で非推奨になり、使うとコンパイル時に警告が出ます。Sass の公式ドキュメントでは、Dart Sass 3.0.0 で削除する予定とされています。新しく書く SCSS では @use(ほかのファイルへ中身をまとめて渡すときは @forward)を使います。

functions.php で読み込む

<?php
// functions.php
add_action( 'wp_enqueue_scripts', function () {
	$path = get_theme_file_path( 'assets/css/main.css' );

	wp_enqueue_style(
		'my-theme-main',
		get_theme_file_uri( 'assets/css/main.css' ),
		array(),
		file_exists( $path ) ? (string) filemtime( $path ) : null
	);
} );

バージョン番号にファイルの更新時刻を使うと、コンパイルし直すたびに URL の ?ver= が変わり、ブラウザに古い CSS が残りにくくなります。

子テーマで使う場合、get_theme_file_uri() は子テーマにファイルがあれば子テーマのものを、なければ親テーマのものを返します。CSS の読み込み方の詳細は「WordPressのwp_enqueue_scriptsでJSとCSSを読み込む方法」で説明しています。

style.css に直接出力したい場合

どうしても style.css にコンパイルしたい場合は、テーマ情報のコメントを /*! で始めます。--style=compressed は通常のコメントを消しますが、/*! で始まるコメントは残します。

/*!
Theme Name: My Theme
Version: 1.0.0
*/

@use 'base';
@use 'card';

コンパイル後に「外観 > テーマ」でテーマ名が正しく表示されることを確かめます。

@wordpress/scripts でビルドする場合

ブロックの開発などで @wordpress/scripts(wp-scripts コマンド)を使っている場合は、SCSS も一緒にビルドできます。ただし、wp-scripts は SCSS ファイルを単独で探すのではなく、JavaScript から読み込まれた SCSS を処理します。

npm install --save-dev @wordpress/scripts
{
  "scripts": {
    "start": "wp-scripts start",
    "build": "wp-scripts build"
  }
}

src/ に block.json がない場合、入口は src/index.js です。ここで SCSS を読み込みます。

// src/index.js
import './style.scss';  // style.scss という名前のファイル → build/style-index.css
import './editor.scss'; // それ以外の名前のファイル → build/index.css

npm run build を実行すると build/ フォルダーに CSS が出力されます。@wordpress/scripts のドキュメントでは、style.scss などの名前のファイルはフロントとエディターの両方用として style-index.css にまとめられ、それ以外は index.css に出力されると説明されています。@wordpress/scripts 37.1.0 で試すと、build/ には style-index.css・index.css のほか、index.js、index.asset.php(依存関係とバージョンの情報)、右から左に書く言語用の style-index-rtl.css・index-rtl.css が出力されました。出力されたファイル名を build/ で確かめてから、functions.php の wp_enqueue_style() に指定します。

<?php
add_action( 'wp_enqueue_scripts', function () {
	$path = get_theme_file_path( 'build/style-index.css' );

	if ( file_exists( $path ) ) {
		wp_enqueue_style(
			'my-theme-style',
			get_theme_file_uri( 'build/style-index.css' ),
			array(),
			(string) filemtime( $path )
		);
	}
} );

注意点

  • node_modules/ はサーバーに上げません。テーマを ZIP にして配布・アップロードするときも含めないようにします。
  • コンパイル済みの CSS を Git で管理するかはチームで決めます。管理しない場合は、デプロイの前にビルドする手順(CI など)が必要です。
  • サーバー上で SCSS をコンパイルする必要はありません。手元でコンパイルした CSS だけをアップロードします。

まとめ

  • npm install --save-dev sass で Dart Sass を入れ、sass 入力.scss 出力.css でコンパイルする
  • コンパイル結果は assets/css/main.css のような別ファイルに出し、テーマ情報の style.css は上書きしない
  • ファイル分割は @import ではなく @use を使い、変数を使うファイルごとに読み込む
  • 読み込みは wp_enqueue_style() で行い、バージョンにファイルの更新時刻を使うとキャッシュが残りにくい

お気軽にご相談ください

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