zudo-doc

Type to search...

to open search from anywhere

コンポーネントファースト戦略

作成2026年3月22日Takeshi Takatsudo

zudo-docがカスタムCSSクラス名ではなく、ユーティリティクラスを持つコンポーネントを使用する理由。

zudo-docはコンポーネントファースト戦略に従います:UIは常にTailwindユーティリティクラスを持つコンポーネントとして表現します。カスタムCSSクラス名を別のスタイルシートで作成することはしません。

問題

ユーティリティCSSフレームワークとコンポーネントフレームワークを併用するプロジェクトでは、開発者は従来のCSSパターンに戻りがちです。コンポーネント内でユーティリティクラスを組み合わせる代わりに、.profile-card.btn-primary.sidebar-navといったカスタムCSSクラス名を別のスタイルシートやCSSモジュールで作成します。

これにより、コードベースが断片化します:

  • ユーティリティをインラインで使うコンポーネント
  • カスタムCSSクラスを導入するコンポーネント
  • 両方のアプローチを混在させるコンポーネント

ルール

コンポーネント自体が抽象化です。 .card.btn-primaryのようなCSSクラス名は不要です。コンポーネントがカプセル化を、ユーティリティクラスがスタイリングを担当します。

  • カードが必要? → ユーティリティクラスを持つ<Card>コンポーネントを作成
  • ボタンバリアント? → <Button variant="primary">コンポーネント
  • レイアウトパターン? → <PageLayout>コンポーネント

zudo-docでの実践

zudo-docはAstroコンポーネント.astro)とReactアイランド.tsx)をTailwind CSS v4ユーティリティとともに使用します。

Astroコンポーネント

<!-- ユーティリティクラスをインラインで使用 -->
<footer class="border-t border-muted bg-surface px-hsp-xl py-vsp-xl">
  <div class="text-center text-caption text-muted">
    <Fragment set:html={copyright} />
  </div>
</footer>

.footerクラスなし。footer.module.cssなし。コンポーネント抽象化です。

アンチパターン

/* 間違い — カスタムCSSクラスを作成しない */
.profile-card { display: flex; gap: 1rem; }
<!-- 間違い — カスタムクラス名はデザインシステムをバイパスする -->
<div class="profile-card">...</div>

<!-- 正しい — ユーティリティクラス、コンポーネントが抽象化 -->
<div class="flex gap-hsp-md p-hsp-lg">...</div>

バリアントはPropsで

CSSモディファイアクラス(.btn--primary)ではなく、コンポーネントプロップスを使用:

function Button({ variant = "primary", children }) {
  const styles = {
    primary: "bg-accent text-bg hover:bg-accent-hover",
    secondary: "bg-surface text-fg border border-muted",
  };
  return (
    <button className={`${styles[variant]} font-semibold py-vsp-xs px-hsp-md rounded`}>
      {children}
    </button>
  );
}

デザイントークンを使用

任意の値ではなく、プロジェクトトークンを常に使用:

<!-- 間違い — 任意の値はデザインシステムをバイパスする -->
<div class="p-[1.2rem] text-[0.875rem]">

<!-- 正しい — デザイントークンを使用 -->
<div class="p-hsp-md text-small text-muted">

利用可能なトークンについてはデザインシステムを参照してください。

カスタムCSSが許容される場合

zudo-docでカスタムCSSが許容される唯一の場所はsrc/styles/global.cssです:

  • コンテンツタイポグラフィ.zd-contentクラスはMDXパイプラインが生成する要素をスタイリング
  • デザイントークン定義 — Tailwindトークンを登録する@themeブロック

それ以外のすべて(すべてのコンポーネント、レイアウト、UI要素)はユーティリティクラスを直接使用します。

ルールのまとめ

  1. 常にコンポーネントを作成 — CSSクラスではなく
  2. ユーティリティクラスを直接使用 — コンポーネントマークアップ内で
  3. CSSモジュールファイルやカスタムクラス名を作成しない
  4. バリアントにはプロップスを使用 — CSSモディファイアではなく
  5. コンポーネントを組み合わせる — より多くのCSSではなく、小さなコンポーネントから複雑なUIを構築
  6. プロジェクトトークンを使用text-fgbg-surfacep-hsp-md、任意の値ではなく

Revision History

AI Assistant

Ask a question about the documentation.