Tailwind CSSの導入と設定:ユーティリティファーストの考え方

概要

Tailwind CSS は、flex・pt-4・text-center のような小さな「ユーティリティクラス」を HTML に直接並べてスタイリングする CSS フレームワークです。本記事では、ユーティリティファーストという設計思想を整理したうえで、導入手順・設定の読み方・実務で効く使い方までを入門者向けにまとめます。

対象は「名前は聞くが、なぜ便利なのかピンときていない」「CSS設計でクラス名に毎回悩む」という方です。前提環境は Node.js 20 以上(執筆時点の LTS は 24 系)/ Vite / Tailwind CSS v4 系です。

ユーティリティファーストとは何か

従来の CSS 設計では、意味のある単位でクラスを定義してからスタイルを書きます。

/* 従来のアプローチ(コンポーネント指向のCSS) */
.card {
  display: flex;
  flex-direction: column;
  padding: 1rem;
  border-radius: 0.5rem;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
<div class="card">...</div>

一見きれいですが、実務では次の問題が起きがちです。

  • .card と .card-large と .card-compact のように、わずかな差分でクラスが増殖する
  • 「この CSS、まだどこかで使われている?」が分からず、消せないスタイルが溜まる
  • クラス名を考えるコスト(命名疲れ)がかかる

ユーティリティファーストは、この「命名して一箇所に書く」をやめ、1つの責務を持つ極小クラスを組み合わせて見た目を作ります。

<div class="flex flex-col p-4 rounded-lg shadow">...</div>

クラス名が「何をするか」をそのまま表しているため、HTML を見ればスタイルが分かります。新しい命名も不要で、CSS ファイルを行き来する必要もありません。

よくある反論と答え

  • 「HTML が汚れるのでは?」 — 慣れると HTML だけでスタイルが読めるメリットが上回ります。繰り返しはコンポーネント化で解決します。
  • 「同じ記述の繰り返しになる」 — 繰り返しが気になる箇所こそ、UI をコンポーネントとして切り出すサインです。CSS のクラスではなく UI 部品で共通化します。

導入手順

1. インストール

Tailwind CSS 本体と、Vite 用の公式プラグインを入れます。

npm install tailwindcss @tailwindcss/vite

v4 では PostCSS・autoprefixer の個別インストールや npx tailwindcss init -p による設定ファイル生成は不要になりました。依存は上記の2つだけで済みます。

> 補足: npm install tailwindcss で入るのは v4 系です(v3 を明示指定しない限り最新が入ります)。本記事も v4 前提で進めます。

2. Vite にプラグインを追加する

vite.config.js に @tailwindcss/vite を追加します。

import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    tailwindcss(),
    // 他のプラグイン(react() など)があればここに併記
  ],
})

v3 で必須だった postcss.config.js と tailwind.config.js の content 設定は、v4 では不要です。Tailwind がプロジェクト内のテンプレートを自動検出して、実際に使われているクラスだけを最終 CSS に含めます。

3. エントリーCSSに読み込みを書く

v4 では @tailwind base; @tailwind components; @tailwind utilities; の3ディレクティブは廃止され、1行の @import に置き換わりました。

/* src/index.css */
@import "tailwindcss";

この1行で、リセット(Preflight)・コンポーネント層・ユーティリティ本体がすべて読み込まれます。あとはアプリのエントリで CSS を読み込めば準備完了です。

// src/main.jsx
import './index.css'

実装例

カウンターUIを例に、ユーティリティだけで組んでみます。

export function Counter({ count, onIncrement }) {
  return (
    <div className="mx-auto mt-10 flex max-w-sm flex-col items-center gap-4 rounded-xl border border-gray-200 p-6 shadow-sm">
      <p className="text-4xl font-bold text-gray-800">{count}</p>
      <button
        onClick={onIncrement}
        className="rounded-md bg-blue-600 px-4 py-2 text-white transition hover:bg-blue-700 active:scale-95"
      >
        カウントアップ
      </button>
    </div>
  )
}

hover:bg-blue-700 のように、状態(hover/focus/active)やブレークポイント(md: lg:)をプレフィックスで表現できるのが Tailwind の強みです。メディアクエリを別途書かずにレスポンシブ対応ができます。

<!-- スマホは縦並び、md以上で横並び -->
<div class="flex flex-col md:flex-row gap-4">...</div>

設定(テーマ)のカスタマイズ

v4 では、デザイントークン(色・余白・フォント)のカスタマイズは JavaScript の設定ファイルではなく、CSS 側の @theme ブロックで行います。CSS 変数としてトークンを定義すると、それに対応するユーティリティが自動で生成されます。

/* src/index.css */
@import "tailwindcss";

@theme {
  --color-brand: #2563eb;
  --color-brand-dark: #1e40af;
  --spacing-18: 4.5rem;
}

これで bg-brand text-brand-dark pt-18 が使えるようになります。既定のトークンはそのまま残り、@theme で定義した分が追加・上書きされます。チームで色や余白を統一したいときは、ここを「唯一の正」にするのがおすすめです。

確認方法

  1. 開発サーバを起動し、class="text-red-500" など適当なユーティリティを付けて色が変わるか見る
  2. 本番ビルド(npm run build)後の CSS サイズを確認する。未使用クラスが除去され、数十KB程度に収まっていれば自動検出が効いている
  3. 消えてはいけないクラスが本番で消える場合は、後述の「動的クラス名の罠」を疑う

注意点

  • 動的クラス名の罠: ` className={text-${color}-500} のように文字列結合で作ると、Tailwind がソース検出で拾えず、最終 CSS に出力されません。クラスは完全な文字列で書くのが基本です。どうしても動的に扱う必要がある場合は、生成されうるクラスを CSS 側で明示的に残す指定(@source inline(...)`)を使います。
  • クラスの肥大化: 1要素のクラスが長くなったら、それはコンポーネント化のサインです。@apply でまとめる手もありますが、多用するとユーティリティファーストの利点が薄れるため、まずは UI 部品化を検討します。
  • 旧構成(v3)からの移行: v3 では npm install -D tailwindcss postcss autoprefixer と npx tailwindcss init -p、tailwind.config.js の content 配列、エントリ CSS の @tailwind base/components/utilities、theme.extend でのトークン追加、という構成でした。既存プロジェクトが v3 の場合はこの構成のまま動きますが、新規に始めるなら本記事の v4 構成が現行の標準です。考え方(ユーティリティファースト)自体は両バージョンで変わりません。

まとめ

  • ユーティリティファーストは「命名して一箇所に書く」をやめ、極小クラスの組み合わせでUIを作る発想
  • v4 では導入が大幅に簡素化され、@tailwindcss/vite プラグインと @import "tailwindcss"; の一行で動く。テンプレートのスキャンは自動検出になった
  • デザイントークンのカスタマイズは CSS 側の @theme で行う
  • 状態・レスポンシブをプレフィックスで表現でき、CSSファイルを行き来しなくて済む
  • 繰り返しは CSS クラスではなく UI コンポーネントで共通化する

「クラス名に悩む時間」をなくせるのが、Tailwind を使い始めて一番効いた変化でした。まずは小さな画面1枚から試すのがおすすめです。

Sources:

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。