📺

初心者向けのUIコンポーネント設計

に公開
2026/01/05

はじめに

こんにちは。東(t-east)です。
社内のオンボーディング資料として、フロントエンドのコンポーネントデザイン周りについてまとめたので、社外公開用に内容を削りつつここにも載せておきます。

この記事で触れないこと

見た目やデザインに関する話以外は今回は触れません。

  • カスタムフックとの整合性(ロジック周りの話はスコープ外です)
  • Container/Presentationalパターン(概念だけは登場していますが触れません)

そもそも、コンポーネントとは

UI(ユーザーインターフェース)を構成する再利用可能な部品のこと

https://design.digital.go.jp/dads/components/
https://ja.react.dev/learn/your-first-component

コンポーネントの種類

概念として3種類に分類できる

ページコンポーネント モデルコンポーネント UIコンポーネント
用途・説明 ページと1対1の関係を持つコンポーネント 何らかのドメインモデルに関連するコンポーネントUserListや、UserDeleteModalなど UIライブラリとして提供できる汎用コンポーネント
ドメインモデルの知識 持つ 持つ 持たない

https://zenn.dev/knowledgework/articles/99f8047555f700

UIコンポーネントの用途

アプリケーションの仕様やドメインモデルに依存しない超汎用コンポーネント
UIライブラリとして提供できる汎用性を持つ

UIコンポーネント設計のポイント

ドメインモデルの知識を完全に取り除き、とにかく汎用的に

全く違うアプリケーションにでも利用可能である粒度であり、アプリケーションの仕様に関する概念が入っていない状態を作る。

また、命名においても一般的に出回っているデザインシステムと同じ命名にしておき、独自の命名は極力避ける。

実際にUIコンポーネントとして外部に提供されているものの単語を選んでおけば間違いない。

https://design.digital.go.jp/dads/components/
https://tailwindcss.com/plus/ui-blocks
https://smarthr.design/products/components/
https://react.ui.audi/?path=/docs/introduction--docs

CSSのコツ

計算をしない

レイアウトはできる限り Tailwind のレイアウトユーティリティ(flex, grid, gap, spacing scale)で組み、calc(100% - 240px) のような数値計算が必要になる設計をそもそも避ける。

【TailwindCSSの場合】

用途 記法
横並び・縦並び flex, grid, gap-*
比率レイアウト flex-1, basis-1/3, grid-cols-3
余白 p-4, mt-6 などspacing scale をつかう

親要素に設定し、CSSを減らす

同じようなスタイルを子要素ひとつひとつに書くのではなく、親にまとめて指定し、継承・コンテキストで制御する。

デザイン定義のための行数・重複が減り、修正が楽になる。

だめな例(text-slate-900を複数呼び出し)

<div>
  <h2 className="text-lg font-semibold text-slate-900">Title</h2>
  <p className="text-sm text-slate-900">Text</p>
  <a className="text-sm text-slate-900 underline">Link</a>
</div>

修正版。一箇所にまとめる

<div className="text-slate-900">
  <h2 className="text-lg font-semibold">Title</h2>
  <p className="text-sm">Text</p>
  <a className="text-sm underline">Link</a>
</div>

先頭・末尾・交互へのスタイリングはJSを使わずCSSで対応する

  • 「1番目の要素だけ余白を消す」
  • 「最後だけボーダーなし」
  • 「奇数行・偶数行で色を変える」

のような、デザインのロジックはJSで書かない。

【JSを使わない方がいい理由】

  • DOM 操作が不要になり、パフォーマンス・シンプルさが上がる
  • ロジックが増えないのでバグが減る
  • CSS の役割で完結することは CSS に閉じる方が、責務分離としてもきれい

Tailwindではfirst:, last:, odd:, even:などがこれに該当する。

https://tailwindcss.com/docs/hover-focus-and-other-states

https://zenn.dev/koda_momo/articles/e94fbed16be8ab

要素同士の距離はMargin、単体で完結する余白はPaddingを使う

この記事にまとまっている。
https://zenn.dev/seya/articles/09545c7503baa4

この考えに従うと、コンポーネント設計において切り出したコンポーネントの一番外側のdivタグにmarginをつけるのはアンチパターンであるということがわかる。


全く同じスタイルを適用する要素はコンポーネント化する

参考

https://offers.jp/media/event-report/a_3060
https://buildersbox.corp-sansan.com/entry/2023/12/10/000000
https://zenn.dev/uzu_tech/articles/common-component-anti-pattern

Atomic Designは難しいので採用しない方がよい

https://zenn.dev/miya_tech/articles/1da21ede685707
https://zenn.dev/sunnyheee/articles/b5c8985af8407a


Width・Heightを固定しない

レイアウト構造のための w-[300px] / h-[200px] のような 固定サイズ指定はできるだけ避ける。
代わりに w-full, max-w-*, flex-*, min-h-* などで余裕を持たせる。

【横幅】

基本は w-full + 親の max-w-md などで制御する

サイドバー等は w-64 など固定してもよいが、テキストコンテンツにはあまり固定幅を使わない

【高さ】

基本は h-auto

ビューポート高を使いたいときは min-h-screen など

「残りの高さ全部」という場合は flex-1をつかう


HTML要素のディスプレイの初期値は覚えておく

各 HTML 要素のデフォルトの display を理解したうえで、
必要なときだけ Tailwind の block, inline-block, flex, grid などで上書きする。

https://developer.mozilla.org/ja/docs/Web/CSS/Reference/Properties/display

株式会社Digeon

Discussion