1つのエンティティ(商品・記事・ユーザー・ウィジェット)に関連する情報をひとまとめにした独立したコンテナ。画像・タイトル・説明文・アクションボタンを1つの枠内に収め、グリッドやリストで並べて表示する。
この記事を読むと、CardとListの使い分け・インタラクティブCardとスタティックCardの区別・CardのARIA実装・画像比率と可読性の設計基準が自分でできるようになります。
1. UI例(Preview / Live)
このカードは、デザインシステム GUNJO の Card 実装(Card / CardHeader / CardTitle / CardDescription / CardContent / CardFooter)です。用途別に組み合わせを切り替えて確認できます(右上 Code で編集可)。
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
1つのエンティティ(商品・記事・ユーザー・メトリクス)に関する情報をひとまとめにしたコンテナUI。一般的に「画像・タイトル・説明・アクションボタン」の組み合わせを枠(カード型の白背景+ボーダーまたはシャドウ)に収める。複数のCardをグリッドやリストで並べて一覧表示するのが典型的な使い方。
Listとの違い:Listは1行のテキスト情報を縦に並べる。Cardは画像・説明・アクションを含むリッチなコンテンツをグリッドで並べる。コンテンツが1種類ならList、複数要素を含むならCard。
Tableとの違い:Tableは複数の属性を列で横比較する。Cardは1エンティティのコンテンツを独立したブロックで表示する。比較が目的ならTable、閲覧が目的ならCard。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- 画像・タイトル・説明・アクションを含むリッチなコンテンツをグリッドで一覧表示する場合
- ECサイトの商品一覧・ブログ記事サムネイル・ダッシュボードウィジェット
- 各アイテムが独立しており、横並びの視覚的比較より個別の魅力訴求が重要な場合
3.2 When NOT to use
- テキスト1行のシンプルな一覧 →
Listを使う - 複数属性を横比較したい →
Tableを使う - スペースが限られており画像が不要 →
Listの方が情報密度が高い
3.3 代替UI(Alternatives)
- テキスト中心の一覧 →
List - データ比較 →
Table - 単一コンテンツの詳細表示 → ページ遷移またはモーダル
4. 設計判断の核(Decision Principles)
Cardの責務は「1エンティティの魅力を伝えて次のアクションに誘導する」こと——Cardの中にCardを入れない。
判断の優先順位:① Cardにするか Listにするか → ② カード全体をリンクにするか部分リンクにするか → ③ 画像の比率固定 → ④ 情報の優先順位(何を最初に目に入れるか)
- カード全体をクリッカブルにする場合は
<a>で全体をラップ:ただし内部にさらに<a>や<button>がある場合はネスト禁止。内部ボタンはevent.stopPropagation()または外部リンクとの棲み分けを設計する - 画像は比率を固定する:
aspect-ratio: 16/9または4/3で統一し、グリッドのガタつきをなくす - 情報の優先順位を決める:「画像 → カテゴリ → タイトル → 説明 → アクション」の順が読み取り順として自然
- カードのアクション数は最大2つ:プライマリアクション(詳細を見る)とセカンダリ(保存・共有など)の2つまで。それ以上はカードを複雑にしすぎている
5. 状態設計(States)
5.1 必須状態(Required)
- Default:通常表示状態
- Hover:影の強調またはborder変化でクリッカブルを示す(クリッカブルCardの場合)
- Focus:フォーカスリングを表示(キーボード操作対応)
5.2 条件付き状態(Conditional)
- Loading(Skeleton):データ取得中のスケルトンUIを表示
- Selected:チェックボックス付きの選択可能Cardで選択済み状態を示す
- Disabled:操作不可のCardをグレーアウト表示
5.3 State Gallery
| 状態 | 必須 | 何を伝えるか |
|---|---|---|
| Default | ✅ | エンティティの情報概要 |
| Hover | ✅ | このCardをクリックして詳細に進めることを示す |
| Focus | ✅ | キーボードフォーカスの現在地 |
| Loading | — | データ取得中であることを示す |
| Selected | — | 選択済みCardの状態 |
6. バリエーション設計(Variants)
Cardのバリアントは「画像の位置」と「インタラクションの有無」で分かれる。
| バリアント | 用途 |
|---|---|
| Media Card(縦型) | 画像上部・コンテンツ下部。記事・商品一覧のグリッド表示 |
| Horizontal Card(横型) | 画像左・コンテンツ右。リスト形式での表示。モバイルでも省スペース |
| Stat Card | 数値・メトリクスを強調するダッシュボードウィジェット型 |
| Clickable Card | カード全体が1つのリンク。<a> でラップ |
| Interactive Card | 内部にボタン・チェックボックスを含む。カード全体リンク不可 |
禁止パターン:Clickable Card(<a>ラップ)の中にさらに <a> を入れる → HTMLの仕様違反・キーボード操作が壊れる。
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン(3つ)
- セマンティクスの欠如:
<div>のみで作成し<article>を使わないためスクリーンリーダーにCardの意味が伝わらない - 画像比率が不統一:画像の縦横比がバラバラでグリッドのカード高さが揃わず、視線の流れが乱れる
- ネストされたリンク:Cardを
<a>でラップしながら内部のボタンも<a>にしてHTMLが壊れる
7.1 Bad(典型3つ)
<div class="card" onClick>でクリッカブルにしてキーボード操作・スクリーンリーダーが壊れる- 画像を
<img>で表示し高さが各カードでバラバラになってグリッドがガタガタになる - Clickable Card の内部に
<a href>を追加してHTMLのネストエラーが発生する
7.2 Good(対になる3つ)
<article>でCardをラップし、クリッカブルなら内部に<a>を配置してカード全体をリンク領域にするaspect-ratio: 16/9またはobject-fit: coverで画像比率を固定し、全カードの高さを統一する- 内部にボタンがある場合はCardを
<a>でラップせず、タイトルのみを<a>にしてボタンと共存させる
7.3 How to fix(手順)
<div>を<article>に変更する- カード全体をリンクにする場合、
<a href>で内部コンテンツをラップしfocus:ringを付与する - 画像コンテナに
aspect-ratio: 16/9+overflow: hiddenを付け、<img>にobject-fit: coverを指定する - 内部に独立したアクションボタンがある場合、Cardレベルのクリックと独立させて
event.stopPropagation()を使う
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
Keyboard
- クリッカブルCardは
Tabでフォーカスでき、Enterでアクティベートできること - Card内のボタン・リンクはそれぞれ独立してフォーカスできること
Focus
- フォーカスリングはCardの背景色と4.5:1以上のコントラストを持つこと
Screen Reader
<article>でラップするとスクリーンリーダーがCard境界を認識できる- Card内の画像には意味のある
altテキストを設定する - いいね・保存などのアイコンボタンには
aria-labelを付与する
<!-- Clickable Card -->
<article>
<a href="/articles/1" class="block focus:ring-2 focus:ring-blue-500">
<img src="..." alt="デザインシステムの作り方の記事サムネイル" />
<div>
<h3>デザインシステムの作り方</h3>
<p>コンポーネントを体系化する実践ガイド</p>
</div>
</a>
</article>
<!-- Interactive Card(内部にボタンあり) -->
<article>
<img src="..." alt="..." />
<div>
<h3><a href="/articles/1">デザインシステムの作り方</a></h3>
<button type="button" aria-label="いいね" aria-pressed="false">♡</button>
</div>
</article>
Touch / Pointer
- Cardのクリック領域は全体に広げる(タップしやすい)
- 内部の小さなボタンは44px以上のタップ領域を確保する
Contrast / Readability
- タイトルテキストは背景色と4.5:1以上のコントラスト比を確保する
- 説明文・メタ情報(日付・カテゴリ)も3:1以上を確保する
10. 実装メモ(Implementation Notes)
- shadcn/ui の
CardコンポーネントはCardHeader/CardContent/CardFooterに分かれており、構造が整理されている。新規プロジェクトでは積極的に活用する - グリッドレイアウトは
grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3でレスポンシブに対応する - ローディングスケルトンは
animate-pulse+bg-gray-200の組み合わせで実装できる
11. 関連リンク
- 関連するUIデザイン原則: 視覚的階層 (Visual Hierarchy), チャンク化 (Chunking), スキャンしやすさ (Scannability), 情報密度の最適化 (Information Density)
- 用語集(定義): 視覚的階層 (Visual Hierarchy), チャンキング (Chunking)
- 関連するUIコンポーネント(横): List(リスト), Table(テーブル / 表), Badge(バッジ), Button(ボタン)
12. まとめ
Cardの設計は「<article>でラップする」と「画像比率を固定する」の2点が最低ラインです。迷ったら 4. 設計判断の核 に戻り、Clickable CardかInteractive Cardかを先に決めてください。Clickable Card(全体リンク)内に <a> をネストするのはHTML仕様違反——内部にボタンがある場合はタイトルのみをリンクにするInteractive Cardパターンに切り替えることが、壊れないCard設計の最短ルートです。