できない.dev

Tailwind CSS で @apply ディレクティブが効かない

@apply は Tailwind の PostCSS プラグインを通った CSS の中でのみ展開される。
CSS Modules や scoped style、別パイプラインで処理された .css では無効化される。
globals.css に書くか、Tailwind v4 では @reference を冒頭に追加する。

公開: 更新:

実行例あり(2026-08-18 に実環境で検証)

要約

@apply はビルド時に Tailwind の PostCSS プラグインがユーティリティクラスを CSS 宣言に展開する。
プラグインが走っていない CSS(CSS Modules・scoped style・別バンドル)では生の @apply text-lg; が残り、エラーになるか単に無視される。
Tailwind v4 では使用側 CSS で @reference を明示する仕様も加わった。

よくある原因

  1. CSS Modules / scoped で書いている: Component.module.css や Vue <style scoped> は Tailwind の処理対象外で、@apply が展開されない。
  2. Tailwind v4 の参照不足: v4 では、@apply を使う各 CSS ファイルの冒頭に @reference "tailwindcss"; が必要。
    これが無いとユーティリティが解決できないエラーになる。
  3. PostCSS 設定の漏れ: postcss.config.js の plugins に tailwindcss が無いと、どの CSS でも展開されない。
  4. @layer 外への記述: @layer components の外で @apply を使うとユーティリティとの詳細度関係が壊れ、意図せず上書きされる。

解決策

1. グローバル CSS にまとめる

/* src/app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
 
@layer components {
  .btn-primary {
    @apply px-4 py-2 rounded bg-blue-600 text-white;
  }
}

functions と directives 公式ガイド(新しいタブで開く) のとおり、ユーティリティに上書きされないように @layer components の中で書くのが基本。

2. Tailwind v4 では @reference を書く

v4 にアップグレード済みの場合、@apply を使う CSS の冒頭に必ず付ける。

/* Button.module.css */
@reference "tailwindcss";
 
.btn {
  @apply px-4 py-2 rounded;
}

CSS Modules でも @reference があれば Tailwind のユーティリティ名を解決できる。

3. PostCSS 設定を確認

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

Next.js / Vite では各フレームワークの Tailwind プラグインが入っていれば自動。
カスタムビルドでは明示的に追加する。

4. scoped style では使わない選択

CSS Modules や Vue scoped でユーティリティを使いたいなら、@apply を諦めて HTML 側で className="px-4 py-2" と直接書く方が Tailwind の設計思想に沿う。

実行例

postcss.config.js の plugins に tailwindcss が入っていないと、同じコマンドを通しても out.css には @apply の行がそのまま残る。
plugins に tailwindcss を追加して流し直すと、.btn-primary が padding と border-radius と background-color に展開される。

$ npx postcss src/styles.css -o out.css
$ cat out.css
@tailwind base;
@tailwind components;
@tailwind utilities;
 
@layer components {
  .btn-primary {
    @apply px-4 py-2 rounded bg-blue-600 text-white;
  }
}
→ @apply が展開されず生のまま残っている
$ npx postcss src/styles.css -o out.css
$ grep -A6 "\.btn-primary" out.css
.btn-primary {
  border-radius: 0.25rem;
  --tw-bg-opacity: 1;
  background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 0.5rem;
→ padding / border-radius / background-color に展開されている

— 2026-08-18 時点の出力

検証環境

検証日
実行環境
node:20Debian GNU/Linux 12 (bookworm)
バージョン
  • Node.js 20.20.2
  • npm 10.8.2
  • Python 3.11.2
  • Git 2.39.5

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

この記事は役立ちましたか?