dev TailwindCSS

Tailwind CSS Breakpoints と Dark Mode を実践で学ぶ - レスポンシブ対応の基本

Tailwind CSS breakpoints(ブレークポイント)とダークモードの実装方法を、実際のコード例とともに4ステップで解説。sm:、md:、dark: プレフィックスの使い方から、デザイン判断の基準まで完全理解できます。

読者がこの記事から得られる知識

この記事では、Tailwind CSS breakpoints(ブレークポイント)の基本概念と、ダークモード対応の実装方法を実践的に学びます。

  • Tailwind CSS の sm:, md: などのブレークポイントプレフィックスの使い方
  • レスポンシブデザインをモバイルファーストで実装する方法
  • dark: プレフィックスを使ったダークモード対応の実装方法
  • ブレークポイントやダークモードの値を決定する際の判断基準
  • 実務でのデザイン判断とユーザー調整の進め方

Tailwind CSS を使ったレスポンシブデザインとダークモード対応について、実際に手を動かしながら理解を深めることができます。

今回ハンズオンした内容

今回は、Tailwind CSS の公式ドキュメント(https://tailwindcss.com/docs/styling-with-utility-classes)の「Media queries and breakpoints」と「Targeting dark mode」のセクションを実践的に学習しました。既存のHTMLコードに含まれる CSS フレームワーク の機能を確認しながら、ブレークポイントとダークモードの動作を理解していきます。

ファイル構造

tailwindcss/
├── src/
│   ├── index.html
│   ├── input.css
│   └── output.css
├── package.json
├── package-lock.json
└── README.md

ステップ1: 既存コードでのブレークポイント動作確認

既存のHTMLファイルには、すでにレスポンシブ対応のプロフィールカードが実装されていました。

<div class="flex flex-col gap-2 p-8 sm:flex-row sm:items-center sm:gap-6 sm:py-4 bg-white rounded-xl shadow-lg">
  <img class="mx-auto block h-24 rounded-full sm:mx-0 sm:shrink-0" src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />
  <div class="space-y-2 text-center sm:text-left">
    <div class="space-y-0.5">
      <p class="text-lg font-semibold text-black">Erin Lindford</p>
      <p class="font-medium text-gray-500">Product Engineer</p>
    </div>
    <button class="px-4 py-1 border border-purple-200 text-sm text-purple-600 font-semibold rounded-full hover:border-transparent hover:bg-purple-600 hover:text-white active:bg-purple-700">
      Message
    </button>
  </div>
</div>

コマンドと操作の意味:
このコードには sm: プレフィックスが複数含まれています。sm: は Tailwind CSS breakpoints の一つで、640px以上の画面幅で適用されるスタイルを指定します。

コマンドと操作を実行する意図:
ブラウザのウィンドウ幅を変更することで、画面サイズに応じてレイアウトがどのように変化するかを確認します。

実行結果:

ブラウザウィンドウを639pxに設定した場合:

639ピクセルの画像
  • プロフィールカードが縦並び(flex-col
  • アバター画像が中央配置(mx-auto
  • テキストが中央揃え(text-center

ブラウザウィンドウを640pxに設定した場合:

640ピクセルの画像
  • プロフィールカードが横並び(sm:flex-row
  • アバター画像が左配置(sm:mx-0
  • テキストが左揃え(sm:text-left

実行結果の解説:
640pxを境界として、レイアウトが縦並びから横並びへと切り替わりました。これは sm: プレフィックスが640px以上で適用されるためです。デフォルト(640px未満)では flex-col が適用され、640px以上では sm:flex-row によって上書きされます。このように、Tailwind CSS ではモバイルファーストのアプローチで、小さい画面向けのスタイルを基本とし、大きい画面向けのスタイルを追加していきます。

ブレークポイントの動作を理解できましたね。次は、実際にブレークポイントを変更してみましょう。

ステップ2: ブレークポイントの変更(sm: から md: へ)

理解を深めるため、ブレークポイントを sm:(640px)から md:(768px)に変更します。

変更前のコード:

<div class="flex flex-col gap-2 p-8 sm:flex-row sm:items-center sm:gap-6 sm:py-4 bg-white rounded-xl shadow-lg">
  <img class="mx-auto block h-24 rounded-full sm:mx-0 sm:shrink-0" src="..." alt="" />
  <div class="space-y-2 text-center sm:text-left">

変更後のコード:

<!-- ↓ ここから変更 -->
<div class="flex flex-col gap-2 p-8 md:flex-row md:items-center md:gap-6 md:py-4 bg-white rounded-xl shadow-lg">
  <img class="mx-auto block h-24 rounded-full md:mx-0 md:shrink-0" src="..." alt="" />
  <div class="space-y-2 text-center md:text-left">
<!-- ↑ ここまで変更 -->

コマンドと操作の意味:
すべての sm: プレフィックスを md: に置き換えます。md: は768px以上の画面幅で適用されるブレークポイントです。

コマンドと操作を実行する意図:
ブレークポイントを変更することで、レイアウトの切り替わるタイミングを調整できることを確認します。

実行結果:

767pxでは縦並びのまま:

767ピクセルの画像

768pxで横並びに切り替わる:

768ピクセルの画像

実行結果の解説:
640px〜767pxの範囲では縦並びレイアウトが維持され、768pxに達した瞬間に横並びレイアウトに切り替わりました。これにより、Tailwind CSS breakpoints の値は固定ではなく、デザインに応じて自由に選択できることが確認できました。

Tailwind のデフォルトブレークポイントは以下の通りです:

  • sm: 640px(スマートフォン横向き・小型タブレット)
  • md: 768px(タブレット)
  • lg: 1024px(ノートPC・小型デスクトップ)
  • xl: 1280px(デスクトップ)
  • 2xl: 1536px(大型デスクトップ)

ブレークポイントの仕組みが理解できたところで、次はダークモード対応を見ていきましょう。

ステップ3: ダークモードの動作確認

既存のHTMLファイルには、ChitChatカードにダークモード対応が実装されていました。

<div class="mx-auto flex max-w-sm items-center gap-x-4 rounded-xl bg-white p-6 shadow-lg outline outline-black/5 dark:bg-slate-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10">
  <img class="size-12 shrink-0" src="https://via.placeholder.com/48x48/3b82f6/ffffff?text=CC" alt="ChitChat Logo" />
  <div>
    <div class="text-xl font-medium text-black dark:text-white">ChitChat</div>
    <p class="text-gray-500 dark:text-gray-400">You have a new message!</p>
  </div>
</div>

コマンドと操作の意味:
このコードには dark: プレフィックスが複数含まれています。dark: はOSやブラウザがダークモードに設定されている場合に適用されるスタイルを指定します。

コマンドと操作を実行する意図:
OSの設定でダークモードを切り替えることで、自動的にスタイルが変化することを確認します。

  • Windows: 設定 → 個人用設定 → 色 → 「ダーク」を選択
  • Mac: システム環境設定 → 一般 → 外観 → 「ダーク」を選択

実行結果:

ダークモードの画像
  • カード背景:白(bg-white) → 濃い青灰色(dark:bg-slate-800
  • "ChitChat"テキスト:黒(text-black) → 白(dark:text-white
  • メッセージテキスト:グレー(text-gray-500) → 明るいグレー(dark:text-gray-400

実行結果の解説:
OSのダークモード設定に応じて、自動的に配色が切り替わりました。dark: プレフィックスは、デフォルトのスタイルを上書きする形で適用されます。例えば、bg-white dark:bg-slate-800 の場合、ライトモードでは bg-white が適用され、ダークモードでは dark:bg-slate-800 が優先されます。

ダークモードの自動切り替えが確認できましたね。次は、自分でダークモード対応を追加してみましょう。

ステップ4: プロフィールカードへのダークモード対応追加

プロフィールカード(Erin Lindford)はダークモード対応していなかったため、dark: プレフィックスを追加します。

変更前のコード:

<div class="flex flex-col gap-2 p-8 md:flex-row md:items-center md:gap-6 md:py-4 bg-white rounded-xl shadow-lg">
  <img class="mx-auto block h-24 rounded-full md:mx-0 md:shrink-0" src="..." alt="" />
  <div class="space-y-2 text-center md:text-left">
    <div class="space-y-0.5">
      <p class="text-lg font-semibold text-black">Erin Lindford</p>
      <p class="font-medium text-gray-500">Product Engineer</p>
    </div>

変更後のコード:

<!-- ↓ ここから変更 -->
<div class="flex flex-col gap-2 p-8 md:flex-row md:items-center md:gap-6 md:py-4 bg-white dark:bg-slate-800 rounded-xl shadow-lg">
  <img class="mx-auto block h-24 rounded-full md:mx-0 md:shrink-0" src="..." alt="" />
  <div class="space-y-2 text-center md:text-left">
    <div class="space-y-0.5">
      <p class="text-lg font-semibold text-black dark:text-white">Erin Lindford</p>
      <p class="font-medium text-gray-500 dark:text-white">Product Engineer</p>
<!-- ↑ ここまで変更 -->
    </div>

コマンドと操作の意味:
色を指定している箇所に dark: プレフィックスを追加します。背景色(bg-*)、テキスト色(text-*)など、色に関するクラスがダークモード対応の対象となります。

コマンドと操作を実行する意図:
ダークモード時にも読みやすい配色にするため、暗い背景に明るいテキストを設定します。

実行結果:

プロフィールカードをダークモードに対応した画像

プロフィールカードもダークモードに対応し、ChitChatカードと統一感のある配色になりました。

実行結果の解説:
ダークモード対応は、色を指定している全ての箇所に dark: プレフィックスを追加することで実装できます。Tailwind CSS の公式サンプルでよく使われる基本パターンは以下の通りです:

  • カード背景:bg-white dark:bg-gray-800
  • メインテキスト:text-gray-900 dark:text-white
  • サブテキスト:text-gray-500 dark:text-gray-400
  • ボーダー:border-gray-200 dark:border-gray-700

このパターンを基本として覚えておけば、多くのケースで対応可能です。基本パターンに該当しない特殊なデザイン(ブランドカラーが強い、グラデーション、高コントラスト要件など)の場合は、ユーザーやクライアントと相談しながら調整していきます。

これで Tailwind CSS breakpoints とダークモードの基本的な使い方が理解できましたね。

ハンズオンの中で私が疑問に感じた点や失敗した点

疑問1: なぜブレークポイントは640pxなのか?

疑問の内容:
sm: のブレークポイントが640pxに設定されている理由は何ですか?特別な根拠があるのでしょうか?

解決手段:
640pxは Tailwind CSS のデフォルト設定に過ぎず、絶対的な基準ではありません。一般的なデバイスサイズを考慮した目安として設定されていますが、プロジェクトのニーズに応じて自由に変更できます。実務では以下のように決定されます:

  • デザインシステムで定義されている場合: 会社やプロジェクトのルールに従う
  • デザインツール(Figma/XD)で指定されている場合: デザイン通りに実装
  • 特に指定がない場合: Tailwind のデフォルト値を使用、または実際に見て調整

疑問2: なぜsm:flex-rowなのか?デザインによるのではないか?

疑問の内容:
公式サンプルでは sm:flex-row が使われていますが、これは必須の使い方なのでしょうか?

解決手段:
完全にデザイン次第です。公式ドキュメントのサンプルは一例に過ぎません。あなたのデザインに応じて、以下のような選択肢があります:

  • 常に横並び: flex flex-row
  • 常に縦並び: flex flex-col
  • 大きい画面でのみ縦並び(逆転): flex flex-row sm:flex-col
  • 中型画面から横並び: flex flex-col md:flex-row

どのブレークポイントでどのレイアウトにするかは、デザイナーとの相談、またはユーザー/クライアントとの調整で決定します。

疑問3: gap-2やp-8などの値はどう決めるのか?

疑問の内容:
gap-2md:gap-6p-8md:py-4 などの具体的な値は、何を根拠に決めているのでしょうか?見た目で適当に決めているのですか?

解決手段:
基本的には「見た目で調整」です。実務では以下のような流れで決定します:

パターン1: デザインツールから指定がある場合

Figma/XDで指定されている値
↓
Tailwindの単位に変換
例: gap 24px → gap-6

パターン2: その場で調整する場合

1. デフォルト値で実装
2. ブラウザで実際に見る
3. 「ちょっと狭いな...」→ gap-6 に変更
4. 繰り返し調整

パターン3: デザインシステムに従う場合

会社やプロジェクトのルール
例: カード内の間隔は gap-4 または gap-6 のみ使用

デザイナーがいる場合は、デザイナーがFigmaなどで指定した値を実装します。デザイナー不在の場合は、開発者が他のWebサイトやUIライブラリ(Tailwind UI、Material Design等)を参考にして実装し、ユーザー/クライアントと直接調整していきます。

疑問4: ダークモード対応の観点は何か?

疑問の内容:
ダークモード対応は、色を指定している箇所が対象ということですが、具体的にはどの箇所を確認すればよいのでしょうか?

解決手段:
ダークモード対応の観点は「色を指定している箇所」です。具体的には以下のクラスが対象となります:

  • 背景色(bg-*
  • テキスト色(text-*
  • ボーダー色(border-*
  • 影(shadow-*

チェックリストとして:

  1. 明るい背景色(bg-white, bg-gray-100 など)→ ダークモード用の暗い色を追加
  2. 暗いテキスト色(text-black, text-gray-900 など)→ ダークモード用の明るい色を追加
  3. 明るいボーダー色(border-gray-200 など)→ ダークモード用の暗い色を追加
  4. 影(shadow-lg など)→ ダークモードでは見えにくいため調整

ダークモード対応は手動設定が必要ですが、コンポーネント化することで効率化できます。

疑問5: ダークモードのカラーパターンに王道はあるのか?

疑問の内容:
ダークモード対応の色の組み合わせについて、王道のパターンや公式のガイドラインはあるのでしょうか?

解決手段:
Tailwind 公式は明確な推奨パターンを提示していませんが、公式ドキュメントのサンプルコードでよく使われる基本パターンがあります:

bg-white → dark:bg-gray-800
text-gray-900 → dark:text-white
text-gray-500 → dark:text-gray-400
border-gray-200 → dark:border-gray-700

このパターンを基本として覚えておき、基本パターンに該当しないケース(ブランドカラーが強い、特殊なUI、アクセシビリティ要件など)では、以下のように対応します:

  • 低予算プロジェクト: Tailwind 公式パターンをそのまま使用
  • 中予算プロジェクト: 基本パターン + 部分的にカスタマイズ
  • 高予算プロジェクト: デザイナー雇用、完全カスタムデザイン

個人開発の場合は、Tailwind 公式パターンを基本として、必要に応じて微調整する方針が最適です。

記載内容の翻訳

Media queries and breakpoints

hoverやfocusステートと同様に、ブレークポイントでプレフィックスを付けることで、異なるブレークポイントで要素をスタイリングできます。例えば、sm: プレフィックスを使うことで、640px以上の画面幅でのみ特定のスタイルを適用できます。

上記の例では、sm: プレフィックスにより、grid-cols-3sm ブレークポイント以上(デフォルトで40rem = 640px)でのみ適用されます。

生成されるCSSは以下のようになります:

.sm\:grid-cols-3 {
  @media (width >= 40rem) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

詳細については、レスポンシブデザインのドキュメントを参照してください。

Targeting dark mode

ダークモードで要素をスタイリングするには、適用したいユーティリティに dark: プレフィックスを追加するだけです。

hoverステートやメディアクエリと同様に、重要なのは、単一のユーティリティクラスがライトモードとダークモードの両方のスタイルを含むことは決してないということです。ダークモードでは複数のクラスを使用してスタイリングします。1つはライトモードのスタイル用、もう1つはダークモードのスタイル用です。

生成されるCSSは以下のようになります:

.dark\:bg-gray-800 {
  @media (prefers-color-scheme: dark) {
    background-color: var(--color-gray-800);
  }
}

詳細については、ダークモードのドキュメントを参照してください。

今回のまとめ

お疲れさまでした。Tailwind CSS breakpoints とダークモードの実装について、実践的に学習できましたね。

今回学習したことは以下の3点です:

  • Tailwind CSS breakpoints(sm:, md: など)を使ったレスポンシブデザインの実装方法と、モバイルファーストのアプローチ
  • dark: プレフィックスを使った CSS フレームワーク でのダークモード対応の実装方法と、色を指定している箇所の特定方法
  • npm パッケージ インストール や watch モード 自動ビルド を活用した開発フローと、デザイン判断の基準やユーザー調整の進め方

それでは、また別の記事でお会いしましょう。Happy coding!

  • LINE
  • -dev, TailwindCSS