1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TailwindCSS】ComponentとUtilityの使い分け

1
Posted at

はじめに

Tailwind CSSを使っていると、「これはComponentとして切り出すべきか?それともUtilityクラスをそのまま使えばいいのか?」と迷う場面が出てきます。

この記事では、ComponentとUtilityの本質的な違いを整理し、どう使い分けるかを具体的なコード例を交えて解説します。Tailwind CSS v4系の@utility構文にも触れながら、保守性の高い設計を目指す指針を提示します。

参考:Distinguishing "Components" and "Utilities" in Tailwind | CSS-Tricks

ComponentとUtilityの定義を見直す

Tailwindのドキュメントや各種記事では、Component・Utilityをおおよそ次のように定義することが多いです。

用語 よくある定義
Component 複数のスタイルをまとめたもの(例:.card.btn
Utility 単一のCSSルールに対応するクラス(例:px-4text-sm

しかし、この定義は本質を捉えきれていません

語源に立ち返ってみましょう。

  • Component(コンポーネント):「より大きな全体を構成する部品」
  • Utility(ユーティリティ):「役に立つもの、有用であること」

この定義に従うと、UtilityはComponentの一種(全体を構成する部品だから)であり、ComponentはUtilityの一種(役に立つから)でもあります。

ComponentとUtilityの境界線は、実は思ったほど明確ではありません。

なぜ境界線が曖昧になるのか

Tailwind CSS v4では、@utility構文を使って複数のスタイルをまとめたクラスを定義できます。

@utility card {
  border: 1px solid black;
  padding: 1rlh;
}
<div class="card"> ... </div>

これは見た目上「Componentっぽい」ですが、@utilityとして定義しています。

つまり、「複数スタイルをまとめたらComponent、単一ルールならUtility」という区分けは技術的な根拠が弱いのです。

実用上の意味のある違い

では、ComponentとUtilityを区別することに意味はないのでしょうか?

ひとつ実用的な違いがあります。それは「スタイルを上書きしたいかどうか」です。

分類 特徴
Component的なスタイル 複数ルールをまとめた基盤。ベースとして使い、状況に応じて上書きされることを想定
Utility的なスタイル 上書きするために使う。個別の調整に用いる

この観点で整理すると、「ComponentとUtilityの違い=ベース定義か、上書き用か」という実用的な軸が見えてきます。

スタイルの上書き:2つのアプローチ

@layer componentsを使う(従来の方法)

@layer components {
  .card {
    border: 1px solid black;
    padding: 1rlh;
  }
}
<!-- border-blue-500でborderを上書き -->
<div class="card border-blue-500"> ... </div>

この方法の問題点

  • @layer componentsをすべてのコンポーネントファイルに書く必要がある
  • インデントが増え、CSSの可読性が下がる
  • @utilityの柔軟性を活かせない

@utility!important修飾子を使う(推奨)

@utility card {
  padding: 1rlh;
  border: 1px solid black;
}
<!-- !important修飾子でborderを上書き -->
<div class="card !border-blue-500"> ... </div>

@utilityとして定義することで、Tailwindのカスケードレイヤーを利用でき、!修飾子で明示的に上書きが可能になります。

!important修飾子とは?
Tailwind CSS v3以降では、クラス名の先頭に!をつけることでそのスタイルに!importantを付与できます。!border-blue-500border-color: blue !importantとして出力されます。

実際のコード例で比較する

シナリオ:カードコンポーネントを状況に応じてカスタマイズしたい

Component定義(@utilityで基盤スタイルをまとめる)

/* tailwind.css または globals.css */
@utility card {
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  padding: 1.5rem;
  background-color: white;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

Utilityで上書きする使用例

<!-- 基本のカード(Componentそのまま) -->
<div class="card">
  <p>通常のカードです</p>
</div>

<!-- Utilityでボーダーカラーを上書き(警告カード) -->
<div class="card !border-yellow-400">
  <p>⚠️ 注意が必要なカードです</p>
</div>

<!-- Utilityで背景色・ボーダーを上書き(強調カード) -->
<div class="card !bg-blue-50 !border-blue-300">
  <p>ℹ️ 情報カードです</p>
</div>

Reactコンポーネントでの活用例

type CardVariant = 'default' | 'warning' | 'info';

// Component(card)をベースに、Utilityで差分を上書き
const variantClasses: Record<CardVariant, string> = {
  default: 'card',
  warning: 'card !border-yellow-400 !bg-yellow-50',
  info: 'card !border-blue-300 !bg-blue-50',
};

type CardProps = {
  variant?: CardVariant;
  children: React.ReactNode;
};

export const Card = ({ variant = 'default', children }: CardProps) => {
  return (
    <div className={variantClasses[variant]}>
      {children}
    </div>
  );
};

参考

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?