Tailwind CSS入門|ユーティリティファーストCSSの基本と実践テクニック

kento_morota 33分で読めます

「CSSのクラス名を考えるのが面倒」「スタイルが肥大化して管理できない」「レスポンシブ対応に毎回苦労する」――こんな悩みを抱えるフロントエンド開発者にとって、Tailwind CSSは革命的なツールです。

Tailwind CSSはユーティリティファーストのCSSフレームワークで、事前に用意された小さなクラスを組み合わせてスタイルを構築します。本記事では、Tailwind CSSのインストールから基本的な使い方、レスポンシブデザイン、カスタマイズまで、実際のコード例とともに初心者向けに徹底解説します。

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

Tailwind CSSを理解するには、まず「ユーティリティファースト」という考え方を理解する必要があります。

従来のCSS設計との違い

従来のCSS設計では、コンポーネントごとにクラス名を付け、そのクラスにスタイルを書きます。BEMやOOCSSのような命名規則も生まれましたが、根本的な課題は解消されませんでした。

<!-- 従来のCSS -->
<div class="card">
  <h3 class="card__title">タイトル</h3>
  <p class="card__description">説明文</p>
  <button class="card__button card__button--primary">詳しく見る</button>
</div>

<style>
.card {
  background: white;
  border-radius: 8px;
  padding: 24px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.card__title {
  font-size: 1.25rem;
  font-weight: bold;
  margin-bottom: 8px;
}
.card__description {
  color: #666;
  margin-bottom: 16px;
}
.card__button--primary {
  background: #3b82f6;
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
}
</style>

Tailwind CSSでは、同じUIを以下のように記述します。

<!-- Tailwind CSS -->
<div class="rounded-lg bg-white p-6 shadow-md">
  <h3 class="mb-2 text-xl font-bold">タイトル</h3>
  <p class="mb-4 text-gray-500">説明文</p>
  <button class="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
    詳しく見る
  </button>
</div>

CSSファイルを一切書かずに、HTMLのクラス属性だけでスタイリングが完結しています。

ユーティリティファーストのメリット

  • クラス名を考える必要がない:命名に悩む時間がゼロに
  • CSSファイルが肥大化しない:未使用のスタイルは自動的に除外される
  • デザインの一貫性:事前定義されたスケールを使うため、間隔や色がバラつかない
  • 変更が安全:スタイルがHTML要素にローカルスコープされるため、他の要素に影響しない
  • チーム開発に強い:慣れれば誰が書いても似たコードになる

Tailwind CSSのインストールと初期設定

Tailwind CSSのセットアップ方法を、主要なフレームワーク別に解説します。

Vite + React環境でのセットアップ

# プロジェクト作成
npm create vite@latest my-app -- --template react-ts
cd my-app

# Tailwind CSSのインストール
npm install -D tailwindcss @tailwindcss/vite

Viteプラグインとして設定します。

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
  ],
});

CSSファイルにTailwindをインポートします。

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

Next.js環境でのセットアップ

# Next.jsプロジェクト作成時にTailwind CSSを選択
npx create-next-app@latest my-app
# 「Would you like to use Tailwind CSS?」で Yes を選択

create-next-appで作成した場合は、設定が自動で完了します。手動で追加する場合は以下の手順です。

# インストール
npm install -D tailwindcss @tailwindcss/postcss postcss
// postcss.config.mjs
const config = {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};
export default config;
/* app/globals.css */
@import "tailwindcss";

基本的なユーティリティクラスの使い方

Tailwind CSSの基本クラスをカテゴリ別に紹介します。

スペーシング(余白)

Tailwindのスペーシングは4pxを1単位とするスケールに基づいています。

<!-- マージン -->
<div class="m-4">全方向16px</div>
<div class="mx-4">左右16px</div>
<div class="my-4">上下16px</div>
<div class="mt-4">上16px</div>
<div class="mb-8">下32px</div>
<div class="ml-auto">左auto(右寄せ)</div>

<!-- パディング -->
<div class="p-6">全方向24px</div>
<div class="px-4 py-2">左右16px、上下8px</div>

<!-- スペーシングスケール -->
<!-- 0=0px, 1=4px, 2=8px, 3=12px, 4=16px, 5=20px, 6=24px, 8=32px, 10=40px, 12=48px -->

タイポグラフィ

<!-- フォントサイズ -->
<p class="text-xs">12px</p>
<p class="text-sm">14px</p>
<p class="text-base">16px(デフォルト)</p>
<p class="text-lg">18px</p>
<p class="text-xl">20px</p>
<p class="text-2xl">24px</p>
<p class="text-4xl">36px</p>

<!-- フォントウェイト -->
<p class="font-normal">通常</p>
<p class="font-medium">ミディアム</p>
<p class="font-semibold">セミボールド</p>
<p class="font-bold">太字</p>

<!-- テキスト配置 -->
<p class="text-left">左揃え</p>
<p class="text-center">中央揃え</p>
<p class="text-right">右揃え</p>

<!-- テキスト色 -->
<p class="text-gray-900">濃いグレー</p>
<p class="text-gray-500">中間グレー</p>
<p class="text-blue-600">青色</p>

<!-- 行間 -->
<p class="leading-relaxed">ゆったりした行間(1.625)</p>
<p class="leading-tight">詰まった行間(1.25)</p>

Flexboxとグリッドレイアウト

<!-- Flexbox -->
<div class="flex items-center justify-between gap-4">
  <div>左のアイテム</div>
  <div>右のアイテム</div>
</div>

<!-- 縦並び(中央寄せ) -->
<div class="flex flex-col items-center justify-center min-h-screen">
  <h1>画面中央のコンテンツ</h1>
</div>

<!-- CSS Grid -->
<div class="grid grid-cols-3 gap-6">
  <div>カラム1</div>
  <div>カラム2</div>
  <div>カラム3</div>
</div>

<!-- レスポンシブグリッド -->
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
  <div>カード1</div>
  <div>カード2</div>
  <div>カード3</div>
</div>

レスポンシブデザインの実装

Tailwind CSSのレスポンシブ対応は、モバイルファーストのアプローチで設計されています。プレフィックスなしのクラスが最小サイズに適用され、ブレイクポイントプレフィックスで大きな画面の表示を指定します。

ブレイクポイントの基本

<!-- デフォルトのブレイクポイント -->
<!-- sm: 640px以上 -->
<!-- md: 768px以上 -->
<!-- lg: 1024px以上 -->
<!-- xl: 1280px以上 -->
<!-- 2xl: 1536px以上 -->

<!-- 実践例:レスポンシブカードレイアウト -->
<div class="p-4 md:p-8 lg:p-12">
  <h1 class="text-2xl md:text-4xl lg:text-5xl font-bold">
    レスポンシブなタイトル
  </h1>
  <div class="mt-8 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
    <!-- モバイル:1列 → タブレット:2列 → デスクトップ:3列 -->
    <div class="rounded-lg bg-white p-6 shadow">カード1</div>
    <div class="rounded-lg bg-white p-6 shadow">カード2</div>
    <div class="rounded-lg bg-white p-6 shadow">カード3</div>
  </div>
</div>

レスポンシブナビゲーションの実装例

<!-- ハンバーガーメニュー(モバイル)⇔ 横並びナビ(デスクトップ) -->
<nav class="bg-white shadow">
  <div class="mx-auto flex max-w-7xl items-center justify-between px-4 py-3">
    <a href="/" class="text-xl font-bold text-gray-900">Logo</a>

    <!-- モバイルではハンバーガーボタンを表示 -->
    <button class="md:hidden" aria-label="メニュー">
      <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
              d="M4 6h16M4 12h16M4 18h16" />
      </svg>
    </button>

    <!-- デスクトップではナビリンクを横並び表示 -->
    <div class="hidden items-center gap-8 md:flex">
      <a href="/about" class="text-gray-600 hover:text-gray-900">会社概要</a>
      <a href="/services" class="text-gray-600 hover:text-gray-900">サービス</a>
      <a href="/blog" class="text-gray-600 hover:text-gray-900">ブログ</a>
      <a href="/contact"
         class="rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700">
        お問い合わせ
      </a>
    </div>
  </div>
</nav>

hidden md:flexは「デフォルトで非表示、768px以上でflexbox表示」を意味し、md:hiddenは「768px以上で非表示」を意味します。

インタラクティブな状態のスタイリング

Tailwind CSSでは、ホバー・フォーカス・アクティブなどの状態をプレフィックスで簡単に指定できます。

ホバー・フォーカス・アクティブ

<!-- ホバーエフェクト付きボタン -->
<button class="rounded-lg bg-blue-600 px-6 py-3 text-white
               transition-colors duration-200
               hover:bg-blue-700
               focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
               active:bg-blue-800">
  送信する
</button>

<!-- ホバーでカードを浮かせる -->
<div class="rounded-lg bg-white p-6 shadow-md
            transition-all duration-300
            hover:-translate-y-1 hover:shadow-xl">
  <h3 class="font-bold">カードタイトル</h3>
  <p class="mt-2 text-gray-500">カードの説明文</p>
</div>

グループホバーとピアセレクタ

親要素のホバー状態に応じて子要素のスタイルを変更するには、groupgroup-hoverを使います。

<!-- 親のホバーで子のスタイルが変わる -->
<a href="#" class="group flex items-center gap-4 rounded-lg p-4
                   transition-colors hover:bg-gray-50">
  <div class="rounded-full bg-blue-100 p-3
              transition-colors group-hover:bg-blue-600">
    <svg class="h-6 w-6 text-blue-600 group-hover:text-white" ...></svg>
  </div>
  <div>
    <h3 class="font-semibold text-gray-900 group-hover:text-blue-600">
      リンクタイトル
    </h3>
    <p class="text-sm text-gray-500">説明文テキスト</p>
  </div>
</a>

<!-- peer:兄弟要素の状態に応じてスタイルを変更 -->
<div>
  <input type="email" placeholder="メールアドレス"
         class="peer rounded border px-4 py-2
                focus:border-blue-500 focus:outline-none
                invalid:border-red-500" />
  <p class="mt-1 hidden text-sm text-red-500 peer-invalid:block">
    正しいメールアドレスを入力してください
  </p>
</div>

ダークモード対応

Tailwind CSSではdarkプレフィックスでダークモードのスタイルを簡単に指定できます。

<!-- ダークモード対応のカード -->
<div class="rounded-lg bg-white p-6 shadow-md
            dark:bg-gray-800 dark:shadow-gray-900/20">
  <h3 class="text-gray-900 dark:text-white">タイトル</h3>
  <p class="mt-2 text-gray-600 dark:text-gray-300">
    説明文テキスト
  </p>
  <button class="mt-4 rounded bg-blue-600 px-4 py-2 text-white
                 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">
    アクション
  </button>
</div>

CSSファイルでダークモードの制御方法を指定できます。

/* app.css */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));

実践的なコンポーネント例

ここでは、実際のWebサイトでよく使われるUIコンポーネントをTailwind CSSで実装します。

ヒーローセクション

<section class="bg-gradient-to-br from-blue-600 to-purple-700">
  <div class="mx-auto max-w-7xl px-4 py-20 sm:px-6 lg:px-8 lg:py-32">
    <div class="text-center">
      <h1 class="text-4xl font-extrabold tracking-tight text-white
                 sm:text-5xl lg:text-6xl">
        プロダクトの
        <span class="block text-blue-200">キャッチコピー</span>
      </h1>
      <p class="mx-auto mt-6 max-w-2xl text-lg text-blue-100">
        プロダクトの説明文。ここにサービスの概要を2〜3行で記述します。
        ユーザーに価値が伝わるよう簡潔にまとめましょう。
      </p>
      <div class="mt-10 flex flex-col items-center gap-4 sm:flex-row sm:justify-center">
        <a href="/signup"
           class="rounded-lg bg-white px-8 py-3 text-lg font-semibold text-blue-600
                  shadow-lg transition-transform hover:scale-105">
          無料で始める
        </a>
        <a href="/demo"
           class="rounded-lg border-2 border-white px-8 py-3 text-lg font-semibold
                  text-white transition-colors hover:bg-white hover:text-blue-600">
          デモを見る
        </a>
      </div>
    </div>
  </div>
</section>

プライシングテーブル

<div class="grid grid-cols-1 gap-8 md:grid-cols-3">
  <!-- Free プラン -->
  <div class="rounded-2xl border border-gray-200 p-8">
    <h3 class="text-lg font-semibold text-gray-900">Free</h3>
    <p class="mt-4">
      <span class="text-4xl font-bold text-gray-900">¥0</span>
      <span class="text-gray-500">/月</span>
    </p>
    <ul class="mt-8 space-y-3">
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        基本機能
      </li>
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        1プロジェクト
      </li>
    </ul>
    <button class="mt-8 w-full rounded-lg border border-gray-300 py-3
                   font-semibold text-gray-700 transition-colors
                   hover:bg-gray-50">
      無料で始める
    </button>
  </div>

  <!-- Pro プラン(おすすめ) -->
  <div class="relative rounded-2xl border-2 border-blue-600 p-8 shadow-lg">
    <span class="absolute -top-4 left-1/2 -translate-x-1/2 rounded-full
                 bg-blue-600 px-4 py-1 text-sm font-semibold text-white">
      人気
    </span>
    <h3 class="text-lg font-semibold text-gray-900">Pro</h3>
    <p class="mt-4">
      <span class="text-4xl font-bold text-gray-900">¥2,980</span>
      <span class="text-gray-500">/月</span>
    </p>
    <ul class="mt-8 space-y-3">
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        全機能利用可能
      </li>
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        無制限プロジェクト
      </li>
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        優先サポート
      </li>
    </ul>
    <button class="mt-8 w-full rounded-lg bg-blue-600 py-3
                   font-semibold text-white transition-colors
                   hover:bg-blue-700">
      Proを始める
    </button>
  </div>

  <!-- Enterprise プラン -->
  <div class="rounded-2xl border border-gray-200 p-8">
    <h3 class="text-lg font-semibold text-gray-900">Enterprise</h3>
    <p class="mt-4">
      <span class="text-4xl font-bold text-gray-900">要相談</span>
    </p>
    <ul class="mt-8 space-y-3">
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        カスタム機能開発
      </li>
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        SLA保証
      </li>
      <li class="flex items-center gap-2 text-gray-600">
        <svg class="h-5 w-5 text-green-500" ...></svg>
        専属サポート
      </li>
    </ul>
    <button class="mt-8 w-full rounded-lg border border-gray-300 py-3
                   font-semibold text-gray-700 transition-colors
                   hover:bg-gray-50">
      お問い合わせ
    </button>
  </div>
</div>

カスタマイズとテーマ設定

Tailwind CSS v4では、CSSファイル内で直接テーマをカスタマイズできます。

カスタムカラーとフォントの設定

/* app.css */
@import "tailwindcss";

@theme {
  /* カスタムカラー */
  --color-brand-50: #eff6ff;
  --color-brand-100: #dbeafe;
  --color-brand-500: #3b82f6;
  --color-brand-600: #2563eb;
  --color-brand-700: #1d4ed8;
  --color-brand-900: #1e3a5f;

  /* カスタムフォント */
  --font-sans: "Noto Sans JP", "Hiragino Sans", sans-serif;
  --font-mono: "JetBrains Mono", "Fira Code", monospace;

  /* カスタムブレイクポイント */
  --breakpoint-3xl: 1920px;

  /* カスタムスペーシング */
  --spacing-18: 4.5rem;
  --spacing-88: 22rem;
}

これによりbg-brand-500text-brand-900のようなクラスが自動的に生成されます。

カスタムユーティリティの追加

/* カスタムユーティリティ */
@utility text-balance {
  text-wrap: balance;
}

@utility scrollbar-hidden {
  scrollbar-width: none;
  &::-webkit-scrollbar {
    display: none;
  }
}

プラグインの活用

Tailwind CSSにはフォームやタイポグラフィ向けの公式プラグインがあります。

# プラグインのインストール
npm install @tailwindcss/typography @tailwindcss/forms
/* app.css */
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";

@tailwindcss/typographyプラグインを使うと、CMSから出力されたHTMLに美しいタイポグラフィを適用できます。

<!-- proseクラスで記事コンテンツを美しく表示 -->
<article class="prose prose-lg mx-auto dark:prose-invert">
  <h1>記事のタイトル</h1>
  <p>段落のテキスト。リンクやリストも自動的にスタイリングされます。</p>
  <ul>
    <li>リスト項目1</li>
    <li>リスト項目2</li>
  </ul>
  <pre><code>console.log('コードブロックも美しく');</code></pre>
</article>

Tailwind CSSのベストプラクティス

最後に、Tailwind CSSを効果的に使うためのベストプラクティスを紹介します。

クラスの並び順を統一する

Tailwind CSSの公式Prettierプラグインを使うと、クラスの並び順が自動的に統一されます。

# インストール
npm install -D prettier-plugin-tailwindcss
// .prettierrc
{
  "plugins": ["prettier-plugin-tailwindcss"]
}

コンポーネント化で重複を排除する

同じスタイルの繰り返しが多い場合は、ReactやVueのコンポーネントとして切り出しましょう。Tailwindでは@applyよりもコンポーネント化が推奨されています。

// components/Button.tsx
type ButtonProps = {
  variant?: 'primary' | 'secondary' | 'outline';
  size?: 'sm' | 'md' | 'lg';
  children: React.ReactNode;
} & React.ButtonHTMLAttributes<HTMLButtonElement>;

const variants = {
  primary: 'bg-blue-600 text-white hover:bg-blue-700',
  secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
  outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50',
};

const sizes = {
  sm: 'px-3 py-1.5 text-sm',
  md: 'px-5 py-2.5 text-base',
  lg: 'px-8 py-3 text-lg',
};

export function Button({
  variant = 'primary',
  size = 'md',
  children,
  className = '',
  ...props
}: ButtonProps) {
  return (
    <button
      className={`rounded-lg font-semibold transition-colors
                  focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
                  ${variants[variant]} ${sizes[size]} ${className}`}
      {...props}
    >
      {children}
    </button>
  );
}

clsxやtwMergeでクラスを動的に結合する

# インストール
npm install clsx tailwind-merge
// lib/utils.ts
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

// 使用例
import { cn } from '@/lib/utils';

<div className={cn(
  'rounded-lg p-4',
  isActive && 'bg-blue-100 border-blue-500',
  isDisabled && 'opacity-50 cursor-not-allowed',
)}>

twMergeは競合するTailwindクラスを自動的にマージし、後に指定したクラスが優先されます。例えばtwMerge('px-4 px-6')'px-6'を返します。

まとめ

Tailwind CSSは、ユーティリティファーストという新しいアプローチでCSS開発の課題を解決するフレームワークです。本記事で解説した内容をまとめます。

  • ユーティリティファースト:小さなクラスを組み合わせてスタイルを構築し、クラス名の命名やCSSの肥大化の問題を解消
  • レスポンシブデザインsm: md: lg:のプレフィックスでモバイルファーストなレスポンシブ対応
  • インタラクションhover: focus: dark:のプレフィックスで状態のスタイリング
  • カスタマイズ@themeディレクティブでカラーやフォントを自由に設定
  • コンポーネント化:ReactやVueのコンポーネントで重複を排除

最初はクラスの多さに戸惑うかもしれませんが、1週間も使えば自然とクラス名が身につきます。まずは小さなプロジェクトから始めて、ユーティリティファーストの開発体験を味わってみてください。公式ドキュメント(tailwindcss.com/docs)も非常に充実しているので、困ったときはぜひ参照しましょう。

#Tailwind CSS#CSS#フロントエンド
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

起業準備に役立つ情報、もっとありますよ。

まずは話だけ聞いてもらう