Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第3章 Tailwind CSS の設計思想

第1章で歴史を、第2章で誕生の経緯を見てきました。この章では、Tailwind の根っこにある Utility First(ユーティリティファースト) という思想を、メリットだけでなく、それに向けられる批判への反論まで含めて、じっくり理解します。ここを腰を据えて理解しておくと、第4部以降で個々のクラスを学ぶときの「なぜこう書くのか」がすべてつながります。

3.1 Utility First とは何か

Utility First とは、単一の役割だけを持つ小さなクラス(ユーティリティクラス)を組み合わせて、デザインを組み立てるという考え方です。「まずユーティリティで作る」から Utility First です。

具体例を見ましょう。よくある「カード」の UI を、従来の方法と Tailwind で書き比べます。

従来の方法(BEM 風):

<div class="card">
  <h2 class="card__title">通知</h2>
  <p class="card__body">新しいメッセージがあります。</p>
</div>
.card {
  max-width: 24rem;
  padding: 1.5rem;
  background-color: white;
  border-radius: 0.5rem;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.1);
}
.card__title {
  font-size: 1.25rem;
  font-weight: 700;
}
.card__body {
  color: #4b5563;
}

Tailwind の方法:

<div class="max-w-sm p-6 bg-white rounded-lg shadow">
  <h2 class="text-xl font-bold">通知</h2>
  <p class="text-gray-600">新しいメッセージがあります。</p>
</div>

Tailwind 版では、CSS ファイルを 1 行も書いていませんmax-w-sm(最大幅)、p-6(内側の余白)、bg-white(背景白)、rounded-lg(角丸)、shadow(影)といったユーティリティクラスを HTML 側で組み合わせるだけで、同じ見た目を作っています。

このとき生成される CSS は、おおよそ次のような単機能のルールの集まりです(実際の出力は簡略化しています)。

.p-6 { padding: 1.5rem; }
.bg-white { background-color: #fff; }
.rounded-lg { border-radius: 0.5rem; }
/* ... 使ったクラスの分だけ ... */

ポイントは、これらのクラスはこのカード専用ではないことです。p-6bg-white も、サイト中のどこでも何度でも使い回せます。だから、新しい部品を作っても CSS は増えません。

従来は CSS が HTML に依存し、Tailwind は HTML が CSS に依存することを示す図
図 3-1 依存の向きの反転。`.hero-title` 方式は CSS → HTML に依存し、Tailwind は HTML → CSS に依存する。

3.2 なぜインラインスタイルではダメなのか

ここで多くの人が抱く疑問があります。「クラスをたくさん並べるくらいなら、style 属性で直接書くインラインスタイルと同じでは?」というものです。

<!-- インラインスタイル -->
<div style="padding: 1.5rem; background-color: white; border-radius: 0.5rem;">...</div>

見た目だけなら、確かに似ています。しかし Tailwind のユーティリティには、インラインスタイルにはできないことが 3 つあります。これが決定的な差です。

(1) 制約(デザインの一貫性)

インラインスタイルでは padding: 13px でも padding: 17px でも何でも書けてしまいます。自由すぎて、気づけば余白がバラバラになります。一方 Tailwind の p-4p-6p-8 は、あらかじめ決められたスケール(4px 刻みなど)の上に乗っています。選べる値が制限されているからこそ、誰が書いても余白や色が揃い、デザインに一貫性が生まれます。これは「制約は不自由ではなく、品質を守る仕組み」という Tailwind の重要な思想です(3.3 で詳述)。

(2) 状態(ホバー・フォーカスなど)

インラインスタイルでは、:hover:focus のような状態に応じたスタイルが書けません。マウスを乗せたら色を変える、といったことが style 属性では不可能です。Tailwind なら hover:bg-blue-700 のように、バリアントを付けるだけで状態に対応できます。

<button class="bg-blue-500 hover:bg-blue-700">送信</button>

(3) レスポンシブ(画面幅への対応)

インラインスタイルではメディアクエリ(画面幅に応じた切り替え)が書けません。Tailwind なら md: のようなバリアントで対応できます。

<div class="text-sm md:text-lg">画面が広いと大きい文字</div>

この (2)(3) ができることこそ、「Tailwind はインラインスタイルとは違う」と言える根拠です。公式ドキュメントも、ユーティリティクラスを使う理由として、まさにこの「制約・状態・レスポンシブ」を挙げています。

3.3 「制約のあるデザイン」がもたらす一貫性

3.2 で触れた「制約」を、もう少し深く見ます。これは Tailwind を理解するうえで最も大切な発想の 1 つです。

たとえば文字色を考えてみましょう。CSS では color に約 1,600 万色を指定できます。自由です。しかしチーム開発では、この自由がバラつきを生みます。ある人は #3b82f6、別の人は #3c83f5、また別の人は #3a80f0——ほとんど同じだけれど微妙に違う青が、サイト中に散らばっていきます。

Tailwind は、色を blue-500blue-600 のような決められたパレットとして提供します。選択肢を絞ることで、「誰が書いても同じ青になる」状態を作ります。余白も --spacing を基準にした段階的な値(p-4p-6p-8…)として扱い、フォントサイズも sm/base/lg/xl…と段階が決まっています。

これは デザイントークン(デザイン上の決め事を、値の一覧として定義したもの)の考え方そのものです。Tailwind を使うということは、暗黙のうちに「制約のあるデザインシステムの上で作業する」ことを意味します。だからこそ、デザイナーがいなくても、ある程度整った見た目になりやすいのです。この制約は第5章「テーマシステム」で自分好みにカスタマイズできます。

3.4 関心の分離の再定義 — 分けるべきは HTML と CSS ではない

第2章で見た Adam Wathan の主張を、ここで改めて整理します。彼の主張はこうです。

本当に分けるべきなのは「HTML と CSS」ではなく、「再利用できないもの」と「再利用できるもの」だ。

従来の .card__title のようなクラスは、「カードのタイトル」という特定の文脈に縛られていて再利用できません。ファイルは分かれていても、HTML の都合に CSS が縛られています。

Tailwind のユーティリティは逆です。text-xlfont-bold も、特定の文脈に縛られておらず、どこでも再利用できます。HTML 側は「このユーティリティたちを使う」と宣言するだけ。依存の向きが「CSS → HTML」から「HTML → CSS」へ反転しています。

この反転によって、CSS は「特定のページのための、消すのが怖いコード」ではなく、「どこでも使える、安定した部品の集まり」になります。これが Tailwind の言う「関心の分離の再定義」です。

3.5 命名からの解放

第1章で、BEM の大きな負担は「命名」だと述べました。Tailwind は、この負担をほぼゼロにします。

p-6 bg-white rounded-lg shadow と書くとき、あなたは何も命名していません。「このカードを何と呼ぶか」「このタイトルのクラス名は何か」を考える必要がないのです。プログラミングで最も難しいことの 1 つが命名だとすれば、その難所を 1 つ丸ごと回避できるのは、地味ですが非常に大きな利点です。

もちろん、繰り返し使う部品は最終的にコンポーネント化します(第6部)。しかし「とりあえず作る」段階で命名を強制されないことは、開発のリズムを大きく軽くします。

3.6 CSS が線形に増えない理由

従来の方法では、ページや部品を追加するたびに CSS が増えました。新しいボタンを作れば新しいクラスと新しいルールが必要で、プロジェクトが大きくなるほど CSS ファイルは際限なく膨らみます。

Tailwind では、CSS の量は「使っているユーティリティの種類数」でほぼ頭打ちになります。p-4 を 1 か所で使おうと 1,000 か所で使おうと、生成される CSS は .p-4 { padding: 1rem; } の 1 つだけだからです。新しいページを 100 個追加しても、すでに使っているユーティリティの組み合わせで作る限り、CSS はほとんど増えません。

公式ドキュメントはこれを「CSS が線形に増えない(your CSS stops growing)」と表現しています。大規模で長期間運用されるプロジェクトほど、この性質は効いてきます。

3.7 「醜い HTML」問題への作者の回答

Tailwind に最もよく向けられる批判が、「クラスが大量に並んで HTML が読みにくい(醜い)」というものです。

<button class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
  送信
</button>

確かに、初めて見ると面食らうでしょう。これに対する作者やコミュニティの回答は、おおむね次のとおりです。

  • トレードオフである: HTML が「にぎやか」になる代わりに、CSS ファイルの肥大化・命名・詳細度の戦いといった、より深刻な問題から解放される。どちらの「醜さ」を引き受けるか、という選択である。
  • 繰り返しはコンポーネント化で解決する: 同じボタンを何度も書くなら、Rails の部分テンプレートや React のコンポーネントとして 1 か所にまとめればよい。そうすれば、長いクラス列が見えるのは定義の 1 か所だけになる(第6部で詳しく扱います)。
  • 見る場所が変わっただけ: 従来は「HTML を見て → CSS ファイルを開いて確認する」必要があった。Tailwind では、要素の見た目はその場の class にすべて書いてある。ファイルを行き来せずに済むという利点の裏返しでもある。

「醜い HTML」は事実として認めつつ、それを上回る利益があり、かつコンポーネント化で実用上は緩和できる——これが Tailwind 側の立場です。この論争は重要なので、第28章「Tailwind CSS への批判と評価」で、批判側の主張も含めて改めて公平に扱います。

3.8 Utility First が向く場面・向かない場面の見取り図

最後に、思想を現実に当てはめるための見取り図を示します。Utility First は万能ではありません。

向いている場面:

  • アプリケーションの UI(管理画面、ダッシュボード、SaaS など)。独自のデザインを、部品を組み合わせて素早く作りたいケース。
  • コンポーネント志向のフレームワーク(React・Vue や、Rails の ViewComponent など)を使っていて、繰り返しをコンポーネントに畳み込めるケース。
  • チームで開発し、デザインの一貫性を仕組みで担保したいケース。

向いていない・慎重になるべき場面:

  • ごく小さな静的ページ 1 枚だけ。導入の手間が利益を上回ることがある。
  • CMS が吐き出す本文 HTML のように、クラスを付けられない外部由来のマークアップを整えたいケース(ただしこれは @tailwindcss/typographyprose で対応できます。第11章)。
  • コンポーネント化の仕組みがなく、同じ長いクラス列を手で何度もコピーするしかない環境。重複が負債になりやすい。

重要なのは、「向くか向かないか」はプロジェクトの性質とチームの体制で決まるということです。第31章「Tailwind CSS を選ぶべきか」で、この判断を具体的なチェックリストに落とし込みます。

ここまでで、Tailwind が「なぜそういう道具なのか」という土台が固まりました。次の第2部では、いよいよ Tailwind が内部でどう動いているのか——魔法に見える仕組みの正体に踏み込んでいきます。

参考資料