Tailwind CSS実践ガイド - ユーティリティファーストCSS

入門 | 55分 で読める | 2024.12.18

公式ドキュメント

このチュートリアルで学ぶこと

  • Tailwind CSSの基本概念
  • レイアウトとスペーシング
  • レスポンシブデザイン
  • カラーとタイポグラフィ
  • 実践的なUIコンポーネント
  • カスタマイズと最適化

前提条件

  • HTMLとCSSの基本知識
  • Node.jsがインストールされていること

プロジェクトのセットアップ

# プロジェクト作成
mkdir tailwind-tutorial
cd tailwind-tutorial
npm init -y

# Tailwind CSSインストール
npm install -D tailwindcss postcss autoprefixer

# 設定ファイル作成
npx tailwindcss init -p

tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
 content: [
 "./src/**/*.{html,js,jsx,ts,tsx}",
 ],
 theme: {
 extend: {},
 },
 plugins: [],
}

src/input.css

@tailwind base;
@tailwind components;
@tailwind utilities;

ビルドコマンド

npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

ポイント: Tailwind CSSはユーティリティファーストのアプローチで、HTMLにクラスを直接記述してスタイルを適用します。CSSファイルを書く量が大幅に減り、開発速度が向上します。

Step 1: 基本的なユーティリティクラス

スペーシング(Padding & Margin)

<!-- Padding -->
<div class="p-4">すべての方向にpadding: 1rem</div>
<div class="px-4">左右にpadding: 1rem</div>
<div class="py-2">上下にpadding: 0.5rem</div>
<div class="pt-8">上にpadding: 2rem</div>
<div class="pb-6">下にpadding: 1.5rem</div>

<!-- Margin -->
<div class="m-4">すべての方向にmargin: 1rem</div>
<div class="mx-auto">左右自動(中央揃え)</div>
<div class="my-8">上下にmargin: 2rem</div>
<div class="mt-4">上にmargin: 1rem</div>
<div class="mb-2">下にmargin: 0.5rem</div>

<!-- 負のMargin -->
<div class="-mt-4">上に負のmargin: -1rem</div>

<!-- スペーシングのスケール -->
<!--
 0: 0px
 1: 0.25rem (4px)
 2: 0.5rem (8px)
 3: 0.75rem (12px)
 4: 1rem (16px)
 5: 1.25rem (20px)
 6: 1.5rem (24px)
 8: 2rem (32px)
 10: 2.5rem (40px)
 12: 3rem (48px)
 16: 4rem (64px)
 ...
-->

サイズ(Width & Height)

<!-- Width -->
<div class="w-full">100%</div>
<div class="w-1/2">50%</div>
<div class="w-1/3">33.333%</div>
<div class="w-64">16rem (256px)</div>
<div class="w-screen">100vw</div>
<div class="max-w-md">max-width: 28rem</div>
<div class="min-w-0">min-width: 0</div>

<!-- Height -->
<div class="h-screen">100vh</div>
<div class="h-full">100%</div>
<div class="h-64">16rem</div>
<div class="min-h-screen">min-height: 100vh</div>

<!-- テキストカラー -->
<p class="text-black"></p>
<p class="text-white"></p>
<p class="text-gray-500">グレー 500</p>
<p class="text-blue-600">青 600</p>
<p class="text-red-500">赤 500</p>

<!-- 背景色 -->
<div class="bg-white">白背景</div>
<div class="bg-gray-100">薄いグレー背景</div>
<div class="bg-blue-500">青背景</div>

<!-- 透明度 -->
<div class="bg-black/50">50%透明の黒</div>
<div class="text-blue-500/75">75%透明の青テキスト</div>

<!-- ボーダーカラー -->
<div class="border border-gray-300">グレーボーダー</div>

Step 2: Flexbox と Grid

Flexbox

<!-- 基本的なFlex -->
<div class="flex">
 <div>Item 1</div>
 <div>Item 2</div>
 <div>Item 3</div>
</div>

<!-- 方向 -->
<div class="flex flex-row">横並び(デフォルト)</div>
<div class="flex flex-col">縦並び</div>
<div class="flex flex-row-reverse">横並び(逆順)</div>

<!-- 配置 -->
<div class="flex justify-start">左寄せ</div>
<div class="flex justify-center">中央</div>
<div class="flex justify-end">右寄せ</div>
<div class="flex justify-between">両端揃え</div>
<div class="flex justify-around">均等配置</div>

<div class="flex items-start">上揃え</div>
<div class="flex items-center">中央揃え</div>
<div class="flex items-end">下揃え</div>

<!-- 中央配置 -->
<div class="flex items-center justify-center h-screen">
 完全に中央
</div>

<!-- 折り返し -->
<div class="flex flex-wrap">
 折り返しあり
</div>

<!-- Gap -->
<div class="flex gap-4">
 <div>Item 1</div>
 <div>Item 2</div>
 <div>Item 3</div>
</div>

<!-- Flex子要素 -->
<div class="flex">
 <div class="flex-1">均等に伸縮</div>
 <div class="flex-none">伸縮しない</div>
 <div class="flex-grow">伸びる</div>
 <div class="flex-shrink-0">縮まない</div>
</div>

Grid

<!-- 基本的なGrid -->
<div class="grid grid-cols-3 gap-4">
 <div>1</div>
 <div>2</div>
 <div>3</div>
 <div>4</div>
 <div>5</div>
 <div>6</div>
</div>

<!-- 列数の指定 -->
<div class="grid grid-cols-1">1列</div>
<div class="grid grid-cols-2">2列</div>
<div class="grid grid-cols-4">4列</div>
<div class="grid grid-cols-12">12列</div>

<!-- 行数 -->
<div class="grid grid-rows-3">3行</div>

<!-- スパン -->
<div class="grid grid-cols-4 gap-4">
 <div class="col-span-2">2列分</div>
 <div>1列</div>
 <div>1列</div>
 <div class="col-span-4">4列分(全幅)</div>
</div>

<!-- 自動フィット -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-4">
 <!-- 200px以上で自動調整 -->
</div>

実践メモ: レスポンシブデザインはモバイルファーストで記述します。sm:、md:、lg:などのブレイクポイントプレフィックスを使って画面サイズごとのスタイルを指定します。

Step 3: レスポンシブデザイン

ブレークポイント

<!--
 sm: 640px以上
 md: 768px以上
 lg: 1024px以上
 xl: 1280px以上
 2xl: 1536px以上
-->

<!-- モバイルファースト -->
<div class="text-sm md:text-base lg:text-lg">
 <!-- デフォルト: small -->
 <!-- md以上: base -->
 <!-- lg以上: large -->
</div>

<!-- レスポンシブなグリッド -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
 <!-- モバイル: 1列 -->
 <!-- sm: 2列 -->
 <!-- lg: 3列 -->
 <!-- xl: 4列 -->
</div>

<!-- レスポンシブな表示/非表示 -->
<div class="hidden md:block">mdサイズ以上で表示</div>
<div class="block md:hidden">mdサイズ未満で表示</div>

<!-- レスポンシブなFlexbox -->
<div class="flex flex-col md:flex-row gap-4">
 <!-- モバイル: 縦並び -->
 <!-- md以上: 横並び -->
</div>

実践例:レスポンシブヘッダー

<header class="bg-white shadow">
 <div class="container mx-auto px-4">
 <div class="flex items-center justify-between h-16">
 <!-- ロゴ -->
 <a href="/" class="text-xl font-bold">Logo</a>

 <!-- デスクトップナビ -->
 <nav class="hidden md:flex gap-6">
 <a href="/" class="text-gray-600 hover:text-gray-900">ホーム</a>
 <a href="/about" class="text-gray-600 hover:text-gray-900">About</a>
 <a href="/services" class="text-gray-600 hover:text-gray-900">サービス</a>
 <a href="/contact" class="text-gray-600 hover:text-gray-900">お問い合わせ</a>
 </nav>

 <!-- モバイルメニューボタン -->
 <button class="md:hidden p-2">
 <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
 </svg>
 </button>
 </div>
 </div>
</header>

Step 4: タイポグラフィ

フォントサイズ

<p class="text-xs">Extra Small (0.75rem)</p>
<p class="text-sm">Small (0.875rem)</p>
<p class="text-base">Base (1rem)</p>
<p class="text-lg">Large (1.125rem)</p>
<p class="text-xl">Extra Large (1.25rem)</p>
<p class="text-2xl">2XL (1.5rem)</p>
<p class="text-3xl">3XL (1.875rem)</p>
<p class="text-4xl">4XL (2.25rem)</p>
<p class="text-5xl">5XL (3rem)</p>

フォントウェイト

<p class="font-thin">Thin (100)</p>
<p class="font-light">Light (300)</p>
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semibold (600)</p>
<p class="font-bold">Bold (700)</p>
<p class="font-extrabold">Extrabold (800)</p>

テキストスタイル

<!-- 行間 -->
<p class="leading-tight">狭い行間</p>
<p class="leading-normal">通常の行間</p>
<p class="leading-loose">広い行間</p>

<!-- 文字間隔 -->
<p class="tracking-tight">狭い文字間隔</p>
<p class="tracking-wide">広い文字間隔</p>

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

<!-- テキスト装飾 -->
<p class="underline">下線</p>
<p class="line-through">取り消し線</p>
<p class="no-underline">下線なし</p>

<!-- テキスト変換 -->
<p class="uppercase">UPPERCASE</p>
<p class="lowercase">lowercase</p>
<p class="capitalize">Capitalize</p>

<!-- テキストの切り詰め -->
<p class="truncate">長いテキストを切り詰めて...</p>
<p class="line-clamp-2">2行で切り詰め</p>

注意: hover:やfocus:などの状態バリアントを使いすぎるとクラス名が長くなりがちです。繰り返しパターンはコンポーネント化して可読性を保ちましょう

Step 5: 状態とインタラクション

ホバー・フォーカス

<!-- ホバー -->
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
 ホバーで色が変わる
</button>

<!-- フォーカス -->
<input
 class="border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/50 rounded px-3 py-2 outline-none"
 placeholder="フォーカスでスタイル変更"
/>

<!-- アクティブ -->
<button class="bg-blue-500 active:bg-blue-700 text-white px-4 py-2 rounded">
 クリック時に色が変わる
</button>

<!-- 複数の状態 -->
<a
 href="#"
 class="text-blue-500 hover:text-blue-700 hover:underline focus:outline-none focus:ring-2"
>
 リンク
</a>

グループホバー

<div class="group cursor-pointer p-4 border rounded hover:bg-gray-50">
 <h3 class="font-bold group-hover:text-blue-500">
 タイトル
 </h3>
 <p class="text-gray-600 group-hover:text-gray-900">
 説明文
 </p>
 <span class="text-blue-500 opacity-0 group-hover:opacity-100 transition-opacity">
 詳細を見る →
 
</div>

ダークモード

<!-- darkクラスを親要素に追加して切り替え -->
<div class="dark">
 <div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white p-4">
 ダークモード対応コンテンツ
 </div>
</div>

Step 6: 実践的なコンポーネント

カード

<div class="bg-white rounded-lg shadow-md overflow-hidden max-w-sm">
 <img
 src="https://via.placeholder.com/400x200"
 alt="Card image"
 class="w-full h-48 object-cover"
 />
 <div class="p-6">
 <span class="text-xs font-semibold text-blue-500 uppercase tracking-wide">
 カテゴリ
 
 <h2 class="mt-2 text-xl font-bold text-gray-900">
 カードタイトル
 </h2>
 <p class="mt-2 text-gray-600">
 カードの説明文がここに入ります。複数行に渡る場合もあります。
 </p>
 <div class="mt-4 flex items-center justify-between">
 <span class="text-2xl font-bold text-gray-900">¥1,980
 <button class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition-colors">
 購入する
 </button>
 </div>
 </div>
</div>

フォーム

<form class="max-w-md mx-auto space-y-6">
 <div>
 <label class="block text-sm font-medium text-gray-700 mb-1">
 お名前
 </label>
 <input
 type="text"
 class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-shadow"
 placeholder="山田 太郎"
 />
 </div>

 <div>
 <label class="block text-sm font-medium text-gray-700 mb-1">
 メールアドレス
 </label>
 <input
 type="email"
 class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-shadow"
 placeholder="example@email.com"
 />
 </div>

 <div>
 <label class="block text-sm font-medium text-gray-700 mb-1">
 お問い合わせ内容
 </label>
 <textarea
 rows="4"
 class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-shadow resize-none"
 placeholder="ご質問やご要望をご記入ください"
 ></textarea>
 </div>

 <div class="flex items-center">
 <input
 type="checkbox"
 id="terms"
 class="w-4 h-4 text-blue-500 border-gray-300 rounded focus:ring-blue-500"
 />
 <label for="terms" class="ml-2 text-sm text-gray-600">
 利用規約に同意する
 </label>
 </div>

 <button
 type="submit"
 class="w-full py-3 bg-blue-500 hover:bg-blue-600 text-white font-semibold rounded-lg transition-colors"
 >
 送信する
 </button>
</form>

ナビゲーションタブ

<div class="border-b border-gray-200">
 <nav class="flex -mb-px">
 <a
 href="#"
 class="px-6 py-3 border-b-2 border-blue-500 text-blue-500 font-medium"
 >
 ホーム
 </a>
 <a
 href="#"
 class="px-6 py-3 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
 >
 プロフィール
 </a>
 <a
 href="#"
 class="px-6 py-3 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"
 >
 設定
 </a>
 </nav>
</div>

アラート

<!-- 成功 -->
<div class="flex items-center p-4 bg-green-50 border-l-4 border-green-500 text-green-700">
 <svg class="w-5 h-5 mr-3" fill="currentColor" viewBox="0 0 20 20">
 <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"/>
 </svg>
 <span>正常に保存されました。
</div>

<!-- エラー -->
<div class="flex items-center p-4 bg-red-50 border-l-4 border-red-500 text-red-700">
 <svg class="w-5 h-5 mr-3" fill="currentColor" viewBox="0 0 20 20">
 <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z"/>
 </svg>
 <span>エラーが発生しました。
</div>

<!-- 警告 -->
<div class="flex items-center p-4 bg-yellow-50 border-l-4 border-yellow-500 text-yellow-700">
 <svg class="w-5 h-5 mr-3" fill="currentColor" viewBox="0 0 20 20">
 <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"/>
 </svg>
 <span>注意が必要です。
</div>

ベストプラクティス

  1. モバイルファースト
  • デフォルトでモバイルスタイル
  • ブレークポイントで拡張
  1. クラスの整理
  • レイアウト → スペーシング → サイズ → 色 → その他
  • Prettier pluginで自動整理
  1. コンポーネント抽出
  • 繰り返しパターンはコンポーネント化
  • @apply でカスタムクラス作成
  1. パフォーマンス
  • 本番ビルドで未使用クラス削除
  • JITモードで高速ビルド

まとめ

Tailwind CSSはユーティリティファーストのアプローチで、素早くUIを構築できます。基本的なクラスを覚えれば、HTMLだけで柔軟なデザインが可能になります。レスポンシブやダークモードも簡単に対応でき、モダンなWebサイト制作に最適です。

参考リソース

← 一覧に戻る
PR
PR
PR
PR