ユーティリティファーストという選択肢
レッスン6:ユーティリティファーストという選択肢
このレッスンで学ぶこと
- ユーティリティクラスという発想を理解する
- Tailwind CSS が広めた考え方の概要を理解する
- BEM 的な設計との比較を通じて、それぞれの特徴を理解する
- 何を優先するかで設計方針を選ぶという視点と、混ぜて使うときの線引きを身につける
前回のレッスンでは、ボタンやカードを部品として設計する考え方を学びました。今回は、その考え方とは対照的な発想である「ユーティリティファースト」という選択肢を取り上げます。どちらが優れているかという話ではなく、選択肢が 2 つあるという事実を知ることが目的です。
ユーティリティクラスという発想
これまでのレッスンでは、.card や .button のように、役割にもとづいた名前のクラスを 1 つ作り、その中に複数の CSS プロパティをまとめる書き方をしてきました。
.card {
padding: 16px;
margin-bottom: 16px;
border-radius: 4px;
background: #ffffff;
}
ユーティリティクラスは、これとは逆の発想を取ります。1 つのクラスに、1 つの CSS プロパティだけを対応させるという発想です。
.p-4 { padding: 16px; }
.mb-4 { margin-bottom: 16px; }
.rounded { border-radius: 4px; }
.bg-white { background: #ffffff; }
<div class="p-4 mb-4 rounded bg-white">カードのような見た目</div>
先ほどの .card と同じ見た目を、4 つの小さなクラスを組み合わせて表現しています。それぞれのクラスは「余白を付ける」「角を丸める」「背景を白にする」という単一の役割しか持ちません。HTML 側に複数のクラスを並べることで、見た目を組み立てていく書き方です。
📝 補足 「ユーティリティ」は英語で「実用品・道具」を意味します。1 つ 1 つのクラスが、特定の見た目を作るための小さな道具として機能するという意味合いです。
Tailwind CSS が広めた考え方
ユーティリティファーストという考え方を広く知らしめた CSS フレームワークの 1 つに、Tailwind CSS があります。あらかじめ大量のユーティリティクラス(余白・色・文字サイズ・配置などに対応するクラス)が用意されており、開発者は CSS ファイルをほとんど書かずに、用意されたクラスを HTML に並べるだけで見た目を組み立てられます。
<button class="px-4 py-2 rounded bg-blue-600 text-white">
保存する
</button>
このボタンは、.button のような独自のクラスを 1 つも作らずに、内側の余白・角丸・背景色・文字色をすべて既存のユーティリティクラスの組み合わせだけで表現しています。新しく CSS ファイルに何かを書き足す必要がありません。
📖 もっと詳しく 本レッスンでは、ユーティリティファーストという考え方の概要と、既存の設計との比較にとどめます。具体的な導入手順や設定は本コースの範囲を超えるため扱いません。考え方の土台を理解しておけば、実際に使う場面になったときの理解が早くなります。
配置や状態もユーティリティで表現する
ユーティリティクラスは、余白や色だけでなく、配置や状態にも用意されています。
<div class="flex items-center gap-4">
<span>アイコン</span>
<span>テキスト</span>
</div>
flex というユーティリティクラス 1 つで display: flex に相当する指定が適用され、items-center や gap-4 がそれぞれ整列や間隔に対応します。レッスン4 までに学んだ配置の考え方を、CSS ファイルを書かずに HTML 側のクラスだけで再現できる点が特徴です。
状態の表現にも専用の書き方が用意されています。マウスが乗ったときや、キーボード操作でフォーカスが当たったときだけ見た目を変えたい場合、状態名を接頭辞にしてクラス名をつなげます。
<button class="px-4 py-2 rounded bg-blue-600 hover:bg-blue-700 focus:ring">
送信する
</button>
hover:bg-blue-700 は「マウスが乗ったときだけ背景色を変える」という意味で、focus:ring は「フォーカスが当たったときだけ輪郭を表示する」という意味です。レッスン5 で扱った :hover や :disabled といった疑似クラスの考え方が、ユーティリティクラスの世界にもそのまま引き継がれています。
BEM 的な設計との比較
レッスン2 で扱った BEM のような、役割にもとづくクラス名の設計と、ユーティリティクラスの設計は、それぞれ異なる特徴を持っています。
| 観点 | BEM 的な設計 | ユーティリティファースト |
|---|---|---|
| CSS の量 | 部品ごとに増えていく | 早い段階で頭打ちになりやすい |
| HTML の見た目 | クラス名は少なく、意味が読み取りやすい | クラス名が多く並び、詳細な見た目が読み取れる |
| 見た目の変更 | CSS ファイルを編集する | HTML のクラスを直接書き換える |
| 命名の負担 | 部品ごとに名前を考える必要がある | 名前を考える負担がほとんどない |
| 再利用の単位 | 部品(コンポーネント)単位 | 見た目の断片(余白・色など)単位 |
BEM 的な設計は、レッスン5 で扱った「部品は置かれる場所を知らない」という考え方と相性がよく、意味のある単位で CSS をまとめられます。一方、ユーティリティファーストは、命名を考える負担が少なく、既存のクラスの組み合わせだけで多くの見た目を表現できるため、新しい CSS を増やさずに済む場面が多いという特徴があります。
flowchart LR
A[見た目を変えたい] --> B{どちらの設計か}
B -->|BEM的な設計| C[CSSファイルの該当クラスを編集]
B -->|ユーティリティファースト| D[HTMLのクラスを書き換え]
この図は、見た目を変更する場面で、それぞれの設計がどこを編集の起点にするかという違いを表しています。BEM 的な設計は CSS 側が変更の起点になり、ユーティリティファーストは HTML 側が変更の起点になります。
どちらが正しいかではなく、何を優先するかで選ぶ
ここまでの比較を見ると、「結局どちらが優れているのか」と考えたくなるかもしれません。ですが、本コースの立場は、優劣を決めることではありません。それぞれ優先するものが異なる設計であり、状況に応じて選ぶものだという立場です。
BEM 的な設計が向いているのは、次のような状況です。
- 同じ部品が何十か所にも登場し、部品単位で一括して見た目を変更したい
- デザイナーとエンジニアが「部品」という単位で会話をしたい
- HTML を見たときに、意味のある名前で構造を理解したい
ユーティリティファーストが向いているのは、次のような状況です。
- 見た目のバリエーションが多く、部品ごとに名前を考える負担を減らしたい
- 1 人、または少人数で素早く画面を組み立てたい
- CSS ファイルの行数が増え続けることを避けたい
💡 ポイント 「優先するもの」という言葉がこのレッスンの鍵です。BEM 的な設計は「意味の読み取りやすさ」を優先し、ユーティリティファーストは「新しい CSS を増やさないこと」を優先しています。どちらも CSS が壊れにくくなることを目指している点は共通しています。
混ぜて使うときの線引き
実際の制作では、どちらか一方だけを厳密に使うのではなく、両方を組み合わせる場面もあります。混ぜて使うときに有効な線引きの 1 つは、「繰り返し登場する部品」と「その場限りの調整」を分けることです。
<div class="card mt-8">
<h3 class="card__title">お知らせ</h3>
<p class="card__body">メンテナンスのご案内です。</p>
</div>
.card と .card__title は、何十か所にも登場する部品なので、レッスン5 で扱った役割にもとづく名前を付けています。一方、mt-8(上の余白)は、このカードがこの場所に置かれたときだけ必要になる、その場限りの調整です。部品そのものの見た目は BEM 的な設計で固定し、置かれる場所ごとの微調整だけをユーティリティクラスに任せるという線引きです。
⚠️ 注意 部品の内側の見た目(枠線・角丸・基本の余白など)まで毎回ユーティリティクラスで組み立て直すと、同じ組み合わせがあちこちに重複し、レッスン5 で学んだ「部品は置かれる場所を知らない」という利点が失われます。繰り返し使う部品の骨格は、名前を付けて固定しておくほうが安全です。
線引きが崩れやすい典型的な例を見てみましょう。
<div class="p-4 rounded border border-gray-300 bg-white">お知らせ1</div>
<div class="p-4 rounded border border-gray-300 bg-white">お知らせ2</div>
<div class="p-4 rounded border border-gray-300 bg-white">お知らせ3</div>
まったく同じ組み合わせのユーティリティクラスが、3 か所にそのまま複製されています。この状態は、レッスン3 で扱った「同じ値を 2 回書いたら変数にする」という基準の、クラスの組み合わせ版だと考えられます。この段階まで来たら、役割にもとづく名前を付けて固定するタイミングです。
.notice-card {
padding: 16px;
border-radius: 4px;
border: 1px solid #d1d5db;
background: #ffffff;
}
<div class="notice-card">お知らせ1</div>
<div class="notice-card">お知らせ2</div>
<div class="notice-card">お知らせ3</div>
ユーティリティクラスの組み合わせを固定の名前に置き換えたことで、見た目を変更したいときは .notice-card の定義を 1 か所直すだけで済むようになりました。ユーティリティファーストを採用しているからといって、名前を付けることを禁止されているわけではありません。繰り返しの回数が増えた時点で、必要な部分だけ名前を付けて固定するという判断が可能です。
HTML が読みにくくなるという批判への向き合い方
ユーティリティファーストに対してよく向けられる批判の 1 つが、「クラス名が多く並び、HTML が読みにくくなる」というものです。
<div class="flex items-center justify-between px-4 py-2 rounded bg-gray-100 border border-gray-300">
内容
</div>
たしかに、クラス名が横に長く並ぶと、慣れないうちは見た目の情報を読み取りにくく感じます。この批判に対する向き合い方は 1 つではありませんが、代表的な考え方を 2 つ紹介します。
1 つ目は、繰り返し同じ組み合わせが登場するようになったら、部品として名前を付け直すという考え方です。ユーティリティクラスの組み合わせを毎回 HTML に直接書くのではなく、同じ組み合わせが 3 回、4 回と登場した時点で、これはレッスン3 で扱った「同じ値を 2 回書いたら変数にする」という判断基準と同じ発想です。値の重複だけでなく、クラスの組み合わせの重複にも、同じ考え方が応用できます。
2 つ目は、読みにくさの受け止め方は、何を優先するかで変わるという考え方です。部品の名前を読んで構造を理解する体験を優先するなら、ユーティリティクラスの並びは読みにくく感じられます。一方、HTML を見ただけで実際の見た目(余白・色・配置)が正確にわかることを優先するなら、クラスの並びはむしろ「見た目の仕様書」として機能します。どちらの体験を優先したいかによって、読みにくさの感じ方そのものが変わってきます。
🔰 初学者の方へ 最初は、どちらの設計方針が自分やチームに合っているか判断がつかなくてかまいません。小さな画面をそれぞれの方針で一度組んでみて、あとから見返したときにどちらが理解しやすかったかを比べてみると、判断の材料が増えます。
実習:どちらの設計方針で組むかを考える
次の 2 つの場面について、BEM 的な設計とユーティリティファーストのどちらが向いているかを考えてみましょう。
- 場面A:会社のサイト全体で使う「お知らせカード」を作る。同じ見た目のカードが 30 ページ以上に登場し、デザインが変わったときは一括で変更したい
- 場面B:社内の管理画面で、担当者ごとに異なる細かい調整が必要な一覧画面を、少人数のチームで素早く組み立てたい
手順は次のとおりです。
- それぞれの場面で「繰り返し登場する部品」がどれだけあるかを考える
- それぞれの場面で「命名を考える負担」がどれだけ問題になりそうかを考える
- 本レッスンで示した「BEM 的な設計が向いている状況」「ユーティリティファーストが向いている状況」の一覧と照らし合わせる
- 場面Aと場面Bで、選ぶ設計方針が変わってよいことを確認する
まとめ
このレッスンでは、以下のことを学びました。
- ユーティリティクラスは、1 つのクラスに 1 つの CSS プロパティだけを対応させる発想であること
- Tailwind CSS は、ユーティリティファーストという考え方を広めた CSS フレームワークの 1 つであること
- BEM 的な設計は意味の読み取りやすさを、ユーティリティファーストは新しい CSS を増やさないことを、それぞれ優先していること
- どちらが正しいかではなく、状況に応じてどちらを優先するかで選ぶものであること
- 繰り返し登場する部品と、その場限りの調整を分けると、混ぜて使うときの線引きがしやすくなること
- HTML の読みにくさへの向き合い方は、何を優先するかによって変わること
次のレッスンでは、ここまで学んできた命名・変数・部品化の考え方を統合して、小さなデザインシステムを組み立てる方法を学びます。
確認クイズ
このレッスンの理解度をチェックしましょう。