はじめに 🌟
Fluent UI 2 の Card は、単なる「枠」ではなく、1 つの対象に関する情報と操作をまとめるためのコンテナです。たとえば文書、連絡先、設定項目のように、ひとまとまりで見せたい情報に向いています。
この記事では、まず Fluent UI 2 そのものを簡単に整理し、そのあとで Fluent UI 2 の Card(React)と Fluent UI Blazor の Card を比べます。特に、実装、表示、使い方、アクセシビリティの差が分かるようにまとめます。
参照した公式情報はこちらです。
Fluent UI 2 とは
Fluent UI 2 は、Microsoft のデザインシステム Fluent 2 に沿った UI の考え方とコンポーネント群です。見た目をそろえるだけではなく、情報の優先順位、操作の一貫性、アクセシビリティまで含めて設計されています。
つまり Fluent UI 2 は、「きれいな部品集」ではありません。
利用者が迷わず操作できるように、情報とインタラクションの形を決めるための土台です。
Web では React 系コンポーネントとして提供され、そこから Card のような個別コンポーネントを組み立てます。この記事の主題は Card ですが、前提として「コンポーネントの見た目」よりも「どういう体験を作るか」が重視されている、と押さえておくと理解しやすいです。
今回のゴール ✅
- Fluent UI 2 の Card が何を担うコンポーネントか分かる
- Card のレイアウト、アクセシビリティ、コンテンツ設計の要点を押さえる
- Fluent UI 2 の Card と Fluent UI Blazor の Card の違いを整理する
- どちらをどう使い分けるかの感覚を持てる
Fluent UI 2 の Card は何をするのか
公式の説明では、Card は単一の概念やオブジェクトに関連する情報と操作を持つコンテナです。
たとえば「1 件の文書」「1 人の連絡先」「1 つのおすすめ項目」をまとめて見せる、といった使い方が想定されています。
Card のポイントは、情報を詰め込むことではなく、少ない面積で「何のカードか」をすぐ理解できるようにすることです。
そのため、内容は短く、次の行動につながる形にしておくのが基本です。
Fluent UI 2 の Card の考え方
レイアウト
Fluent UI 2 の Card は、内部構造をかなり柔軟に組めます。公式では次のような部品が案内されています。
CardPreviewCardHeaderCardFooter
Card は縦方向にも横方向にも配置でき、ヘッダー、本文、フッターを役割で分けられます。
また、サイズも固定・自動・ブロックなどのパターンを想定していて、コンテンツ量に合わせて調整しやすいです。
| 観点 | Fluent UI 2 の Card |
|---|---|
| 🧱 構成 | Header / Body / Footer を役割で分けやすい |
| ↔️ 向き | Vertical / Horizontal の両方を想定 |
| 📏 サイズ | 固定、auto、block などの幅広いパターン |
| 🧩 柔軟性 | 用途ごとに構造を組み替えやすい |
アクセシビリティ
Card は見た目だけ整っていても足りません。
公式では、特に次の点が重視されています。
aria-labelaria-describedbyaria-labelledby
また、フォーカスの扱いを focusMode で変えられます。
| 値 | 挙動 |
|---|---|
off |
Card 自体はフォーカスを管理せず、内部アクションだけがフォーカス可能 |
no-tab |
Card にフォーカスを入れ、Tab で内部アクションを巡回し、ESC で抜ける |
tab-exit |
Card にフォーカスを入れ、Tab と ESC のどちらでも外に出られる |
tab-only |
Card はフォーカス可能だが、フォーカスを閉じ込めない |
ここで大事なのは、「クリックできるカード」=「アクセシブルなカード」ではないという点です。
支援技術に意味を伝えるラベルと、キーボードで迷わないフォーカス設計が必要です。
コンテンツ
Card の中身は、bite-sized な情報に向いています。
つまり、長文を詰め込む場所ではなく、まず必要な情報を短く見せて、必要なら詳細ページに進んでもらうための入口です。
公式でも、Card の内容は brief and action oriented に保つよう案内されています。
要するに、Card は「説明の全部」を入れる場所ではなく、最初に知ってほしいことを最短で伝える場所です。
Card の説明では、レイアウト・アクセシビリティ・コンテンツを分けて考えると整理しやすいです。
見た目だけを真似ても、カードとしての体験は完成しません。
Fluent UI 2 の Card と Fluent UI Blazor の Card の比較
ここが本題です。
結論から言うと、Fluent UI 2 の Card は「構造を組む Card」、Fluent UI Blazor の Card は「外枠を提供する Card」という違いがかなり大きいです。
| 観点 | Fluent UI 2 の Card(React) | Fluent UI Blazor の Card |
|---|---|---|
| 🧱 実装 |
CardPreview / CardHeader / CardFooter などの部品で構成する |
Razor コンポーネントとしてコンパイルされ、実際のレンダリング結果では div.fluent-card[role="group"] になる |
| 🖼️ 表示 | 縦・横の配置、選択状態、カード全体のボタン化などを想定 | Fluent テーマのカード枠を持ち、既定で 350px 前後のサイズとカード内のスタイルが付く |
| 🛠️ 使い方 | 「この情報をどう分割するか」から考える | 「この枠に何を入れるか」を考える。必要なら AreaRestricted や MinimalStyle で振る舞いを変える |
| ♿ アクセシビリティ |
aria-* と focusMode を Card 側で扱える |
Card 自体は visual container で semantics を持たない。ARIA は属性追加で補う |
| 📐 サイズ | 用途に応じた多様なサイズ設計を前提 |
Width / Height で明示的に調整する。既定値もある |
| 🧩 専用サブ構造 | あり | なし |
実装の差
React の Card は、Card 自体に意味づけされた構造を持たせやすいです。
一方で Fluent UI Blazor の Card は、Razor コンポーネントとしてコンパイルされたうえで、実際のレンダリング結果では div.fluent-card[role="group"] のような visual container になります。公式ドキュメントでも、semantic ではないこと、子要素を受け取ることが明記されています。
Blazor 側の公開 API では、少なくとも次のようなプロパティがあります。
AreaRestrictedWidthHeightMinimalStyle
つまり Blazor の Card は、コンパイル後の描画結果まで含めて見ると、レイアウトの意味をコンポーネントに持たせるというより、カードの見た目・サイズ・内容制限をまとめて扱うための visual container に近いです。
表示の差
React の Card は、カードの中に「画像」「見出し」「説明」「アクション」を役割分担して配置しやすいです。
横並び・縦並びの違いも、Card の設計として扱えます。
Blazor の Card は、そうした構造を自動では作りません。
FluentCard の中に普通の HTML や Fluent コンポーネントを置いて、見た目と構造を自分で作る形です。さらに、内容は既定でカード領域に制限されるため、長いリストや大きいポップアップ系の子要素は切り詰められることがあります。
そのため、見た目の一貫性は出しやすい一方で、Card らしい情報の切り分けは実装者の責任になります。
使い方の差
React 側は「Card という体験を組む」感覚です。
Blazor 側は「Card の枠に内容を入れ、必要なら表示制限やスタイルも調整する」感覚です。
特に次の違いが大きいです。
- React は、Card 単位でアクセシビリティとフォーカスを設計しやすい
- Blazor は、クリック可能な領域やラベルを中の要素で補うことが多い
- React は、Card の見出し・本文・フッターを部品化しやすい
- Blazor は、レイアウトを
divとコンポーネントの組み合わせで作りつつ、AreaRestrictedとMinimalStyleで出力を調整する
Fluent UI Blazor の Card を使うときは、「Card に何を入れるか」より「中身をどう意味づけするか」を先に考えたほうが安全です。
枠だけ置いても、情報設計は自動では整いません。
コード例
React の Card
import {
Button,
Card,
CardFooter,
CardHeader,
CardPreview,
Text,
} from "@fluentui/react-components";
export function ProjectCard() {
return (
<Card orientation="vertical" focusMode="tab-exit" aria-label="Project dashboard card">
<CardPreview>
<img src="/project-preview.png" alt="Project dashboard preview" />
</CardPreview>
<CardHeader
header={<Text weight="semibold">Project dashboard</Text>}
description="Weekly status and metrics"
/>
<Text>
Progress, alerts, and key metrics are summarized here.
</Text>
<CardFooter>
<Button appearance="primary">Open</Button>
<Button appearance="secondary">Share</Button>
</CardFooter>
</Card>
);
}
この例では、focusMode と aria-label を Card 側で持たせています。
また、ヘッダー・本文・フッターを分けているので、見た目だけでなく意味も伝わりやすいです。
Fluent UI Blazor の Card
<FluentCard AreaRestricted="false" Width="320px" MinimalStyle="true" aria-label="Project dashboard card">
<div class="card-header">
<h3>Project dashboard</h3>
<p>Weekly status and metrics</p>
</div>
<div class="card-body">
<p>Progress, alerts, and key metrics are summarized here.</p>
</div>
<div class="card-footer">
<button type="button">Open</button>
<button type="button">Share</button>
</div>
</FluentCard>
Blazor では、Card 自体にヘッダーやフッターの専用部品があるわけではないので、中身を自分で構造化する形になります。
aria-label は属性として足せますし、Width と Height、AreaRestricted、MinimalStyle で表示の作り方も調整できます。
使い分けの目安
| こうしたい | 向いている方 |
|---|---|
| Card を UI パターンとして強く標準化したい | Fluent UI 2 の Card |
| ヘッダー、本文、フッターを部品で分けたい | Fluent UI 2 の Card |
| 既存の Blazor 画面にカード枠を自然に足したい | Fluent UI Blazor の Card |
| 中身の構造を自分で細かく決めたい | Fluent UI Blazor の Card |
| フォーカスや選択の体験を Card レベルで持たせたい | Fluent UI 2 の Card |
おわりに
Fluent UI 2 の Card は、情報のまとまりをデザインするための Card です。
一方で Fluent UI Blazor の Card は、Fluent テーマに沿った visual container として、見た目・サイズ・内容制限をまとめて調整するための Card と見ると分かりやすいです。
なので、React 側の Card をそのまま Blazor に当てはめると、少し期待がずれます。
特に、レイアウトの部品化、フォーカス制御、Card 自体の意味づけは React 側のほうが強く、Blazor 側は visual container としての振る舞い、既定サイズ、内容制限、MinimalStyle の有無まで含めて読む前提です。
Card を使うときは、まず次の 3 つを決めると迷いにくいです。
- 何の情報を 1 枚にまとめるのか
- どこまでを Card に持たせるのか
- どうやって支援技術とキーボード操作に伝えるのか
この 3 つを先に決めると、見た目だけでなく使い方まで揃えやすくなります。