はじめに 🌟
Fluent UI 2 は、Microsoft のデザインシステムです。単に UI パーツを配るライブラリではなく、そのコンポーネントをどう使うべきか、どんな意味を持たせるべきか、アクセシビリティをどう担保するべきかまで含めて整理されているのが特徴です。Badge もその典型で、見た目は小さな部品でも、情報設計への影響は意外と大きいです。✨
一方で、Blazor 側では FluentBadge を見れば終わり、というほど単純ではありません。特に Fluent UI Blazor 4 と 5 は Badge 周りの API と考え方がかなり違います。古い記事やサンプルをそのまま持ち込むと混乱しやすいため、ここは最初にはっきり分けておきたいところです。👀
本記事では、まず Fluent UI 2 とは何かを整理し、その後で Fluent UI Blazor 5 における Badge を確認します。さらに両者を比較したうえで、Badge の色・サイズ・アクセシビリティ・コンテンツを中心に、実装で迷いやすいポイントをまとめます。🚀
関連する記事として、以前書いた Avatar と Accordion の記事もあります。PresenceBadge や attached badge の文脈では Avatar ともつながるので、あわせて読むと理解しやすいです。
- Fluent UI 2 の Avatar を整理しつつ Fluent UI Blazor 5 でどう実装するか
- Fluent UI 2 の Accordion を理解する — 情報設計・アクセシビリティ・React 実装
今回のゴール 🎯
この記事では、次の点が分かるように整理します。
- ✅ Fluent UI 2 における Badge の役割
- ✅ Fluent UI Blazor 5 における Badge / CounterBadge / PresenceBadge の分担
- ✅ Fluent UI 2 と Fluent UI Blazor 5 の違い
- ✅ Badge の色・サイズ・コンテンツ・アクセシビリティの設計ポイント
- ✅ Fluent UI Blazor 4 と 5 の差分
なお、Blazor 側はデモサイト上で v5.0.0-RC.3 と表示されている内容を前提に整理しています。まずは Fluent UI 2 側の考え方から見ていきます。📘
Fluent UI 2 とは
Fluent UI 2 は、Microsoft 製品群で共通化されているデザインシステムです。見た目の統一だけではなく、状態の伝え方、操作の一貫性、情報の優先順位、アクセシビリティまで含めて設計指針を提供してくれます。🎨
Badge の公式 Usage ページでも、Badge は単なる装飾ではなく、関連するコンポーネントの status または description を伝える visual indicator と説明されています。短いテキスト、色、アイコンを使って素早く認識できるようにし、関連する UI の近くに置く、というのが基本です。
つまり Fluent UI 2 を見るときは、「どう書くか」より先に「何を表現するコンポーネントなのか」を理解するのが大切です。次に、その考え方を Blazor 5 がどう表現しているかを見ます。🧭
Fluent UI Blazor 5 の Badge とは
ここは最初に整理しておきたいのですが、Fluent UI Blazor 5 では Badge 系コンポーネントが 1 個ではありません。デモサイトでは次の 3 つに分かれています。✨
| 表したいもの | Blazor 5 で使うもの | 役割 |
|---|---|---|
| 🏷️ テキストやアイコンで状態を示す | Badge |
一般的なラベル・状態表示 |
| 🔢 数値を示す | CounterBadge |
件数や通知数 |
| 🟢 在席や状態を示す | PresenceBadge |
online / busy などの presence |
この分割はかなり重要です。Fluent UI 2 の「badge 的な表現」を、Blazor 5 は用途ごとに明示的に分けています。この記事で主に扱うのは Badge ですが、CounterBadge と PresenceBadge が別コンポーネントになっていることを先に知っておくと混乱しにくいです。🔍
また、Blazor 5 の FluentBadge は <fluent-badge> web component のラッパーです。Badge を単独表示するだけでなく、関連コンテンツをラップして attached badge として扱えるようになっています。
ここまでで、Fluent UI 2 が設計ガイドで、Blazor 5 がその実装表現だと見えてきました。次に違いを並べます。📊
Fluent UI 2 と Fluent UI Blazor 5 の比較
まず押さえたいのは、比較している対象のレイヤーが違うという点です。Fluent UI 2 は「どう設計するか」という概念寄りのガイドで、Fluent UI Blazor 5 は「それをどの API で表現するか」という実装寄りのライブラリです。
概念レベルでの比較
| 項目 | Fluent UI 2 | Fluent UI Blazor 5 |
|---|---|---|
| 🧭 位置づけ | デザインガイド / Usage | Blazor 実装 |
| 🏷️ 基本概念 | Badge は status / description の visual indicator |
Badge / CounterBadge / PresenceBadge に分割 |
| 📍 配置 | 関連コンテンツの上または近く | wrap して attached badge にできる |
| 🎨 色 | 意図的に使う。warning / danger は解決導線を伴うのが望ましい |
BadgeColor や BackgroundColor で表現 |
| 📏 サイズ | 同じ文脈でサイズを混在させない |
BadgeSize で選択 |
| ♿ フォーカス | 既定では focus を受けない。interactive なら focus を考える | badges は focus を受けるべきではない、というガイドが強い |
| 📝 コンテンツ | 1〜2 語の短い説明。省略や切り詰めを避ける | 長文は非推奨。必要ならアプリ側 CSS で制御 |
API レベルでの比較
| 観点 | Fluent UI Blazor 5 の主な表現 |
|---|---|
| 📝 テキスト | Content |
| 🎨 色 |
Color (BadgeColor) / BackgroundColor
|
| ✨ 外観 |
Appearance (Filled / Ghost / Outline / Tint) |
| 🔵 形状 |
Shape (Circular / Rounded / Square) |
| 📏 サイズ |
Size (Tiny ~ ExtraLarge) |
| 📍 attached badge |
AnchorContent / Positioning / OffsetX / OffsetY
|
| 🧩 アイコン |
IconStart / IconEnd / IconLabel
|
私の理解では、Fluent UI 2 は「Badge をどう設計するか」を教えてくれて、Blazor 5 は「その設計をどの API で表現するか」を教えてくれます。実装時は、この 2 層を分けて考えるとぶれにくいです。🪄
Badge の基本: 何を伝えるコンポーネントか
Fluent UI 2 では、Badge は関連するコンポーネントの状態や説明を補助的に伝えるものです。ここで大事なのは、Badge 自体が主役ではなく、associated component の意味を強化する存在だという点です。📌
たとえば、次のような使い方は自然です。
- 新機能であることを示す
New - 試験的機能であることを示す
Beta - 承認が必要であることを示す
Needs review - 危険状態や警告状態を補助的に示す表示
逆に、Badge だけで重要な判断を完結させる設計は危ういです。Badge は短く、素早く、補助的に意味を足すものだと考えると、設計判断がしやすくなります。次は色です。🎨
色: 見た目ではなく意味で使う 🎨
Fluent UI 2 の Usage では、Badge の色は intentionally 使うべきだとされています。特に semantic color を使うときは、「今どういう状態か」だけではなく、必要なら次に何をすべきかが伝わるようにするのが望ましいです。
たとえば warning や danger を出すなら、単に目立つ色を付けるだけでは不十分です。Badge が「要対応」を示すなら、その近くに解決手段や導線がある方が親切です。⚠️
Blazor 5 側では、ここが API に落ちています。確認できる主な関連パラメーターは次のとおりです。
-
Color(BadgeColorenum) BackgroundColor-
Appearance(BadgeAppearanceenum:Filled/Ghost/Outline/Tint)
特に重要なのは、BackgroundColor を設定する場合は Color を null にする必要があるという制約です。つまり、列挙型による既定の意味付けを使うか、自分で背景色を与えるかを明確に分ける設計になっています。🧩
既定色を使う例
<FluentBadge Content="Beta"
Appearance="BadgeAppearance.Tint"
Color="BadgeColor.Brand" />
ブランド色や semantic color を選ぶ方が、Fluent UI の設計意図に沿いやすいです。
カスタム背景色を使う例
<FluentBadge Content="Preview"
Appearance="BadgeAppearance.Filled"
BackgroundColor="#5C2D91" />
BackgroundColor を使う場合は、コントラストを自分で検証する必要があります。Fluent UI 2 のガイドは「色だけに頼らないこと」を前提にしているので、カスタム色を使うほどアクセシビリティ責任は実装側へ戻ってきます。
つまり色の章で押さえたいのは、設計上は意味で使い、実装上は API 制約とコントラスト責任を理解することです。次はサイズです。📏
サイズ: 混在させないのが基本 📏
Fluent UI 2 では、同じ文脈で badge sizes を混在させないことが推奨されています。Badge は小さくても目につく部品なので、サイズがばらつくと視線誘導が散りやすく、レイアウトの秩序も崩れます。
Blazor 5 ではこの考え方が Size (BadgeSize enum)に落ちています。つまり CSS でその場しのぎに伸ばすより、意味あるサイズ体系の中から選ぶ方が自然です。✨
<FluentBadge Content="New" Size="BadgeSize.Small" />
<FluentBadge Content="Beta" Size="BadgeSize.Small" />
<FluentBadge Content="Draft" Size="BadgeSize.Small" />
単体のデモではいろいろなサイズを見比べたくなりますが、実画面では同一リスト・同一カード群・同一ナビゲーション内で揃える方が読みやすいです。Badge は目立つからこそ、揃えるメリットが大きいと感じます。🧱
コンテンツ: 短く、状態を表す言葉にする 📝
Fluent UI 2 の Usage では、Badge のテキストは short and descriptive、できれば one or two words が推奨されています。英語 UI では sentence-style capitalization を使い、truncation を避けることも明示されています。
この方針は Blazor 5 側でもそのまま重要です。デモでも long text unsupported とされており、Badge に長文を流し込む用途は想定されていません。💡
つまり、Badge の Content に入れるべきなのは次のような短い状態語です。
NewBetaDraftBlockedUrgent
逆に避けたいのは、説明文をそのまま詰め込むことです。
Needs review from approver before publishingThis item has unresolved dependenciesThe user is temporarily unavailable
基本のテキスト Badge
<FluentBadge Content="Draft"
Appearance="BadgeAppearance.Outline"
Color="BadgeColor.Subtle" />
どうしても切り詰めが必要な場合
Fluent UI 2 には built-in の max-width がありません。Blazor 側でも同様に、切り詰めが必要ならアプリ側 CSS で制御する必要があります。
<FluentBadge Content="Needs review from approver"
Class="badge-truncate"
Appearance="BadgeAppearance.Outline"
Color="BadgeColor.Warning" />
.badge-truncate {
max-width: 10rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
ただし、公式ガイドの方向性は「切り詰めを前提にする」より「最初から短く書く」です。私も、Badge は略語や圧縮表現のテクニックより、短い状態語に言い換える設計を先に考える方がよいと思います。✍️
配置: associated content の近くに置く 📍
Fluent UI 2 では、Badge は関連するコンテンツの上または近くに置くべきだとされています。利用者が見た瞬間に「これは何に対する Badge か」が分からないと、Badge はただのノイズになります。
Blazor 5 では、attached badge の表現がかなり分かりやすくなっています。
AnchorContentPositioningOffsetXOffsetY
ここで重要なのは、v5 では badge の文字列が Content に分かれ、関連コンテンツは AnchorContent に置くという構造です。これは v4 の ChildContent 中心の書き方から切り替わるポイントです。🔄
attached badge の例
<FluentBadge Content="New"
Appearance="BadgeAppearance.Filled"
Color="BadgeColor.Brand"
Positioning="Positioning.AboveEnd">
<AnchorContent>
<FluentButton Appearance="Appearance.Outline"
aria-label="通知、New バッジ付き">
通知
</FluentButton>
</AnchorContent>
</FluentBadge>
このパターンでは、Badge がボタンに関連付いた attached badge として扱えます。Blazor 5 では 9 つの位置に配置でき、既定位置は AboveEnd です。必要なら Positioning、OffsetX、OffsetY で微調整できます。🧲
ここは Fluent UI 2 の「near associated content」という原則を、Blazor 5 がかなり実装しやすい形で提供している部分だと感じます。次はアクセシビリティです。♿
アクセシビリティ: Badge 自体より文脈が重要 ♿
Badge のアクセシビリティで重要なのは、Badge だけを見て完結させないことです。Fluent UI 2 と Blazor 5 の両方で、かなり共通する注意があります。
1. Badge は既定でフォーカスを受けない
Fluent UI 2 の Usage では、Badge は既定では focus を受けません。もし tooltip などで interaction を持たせるなら focus を含める必要があります。
一方で Blazor 5 側のデモでは、badges should not receive focus と、より強く非インタラクティブ前提で説明されています。さらに v5 では OnClick が削除されているため、v4 のように Badge をそのまま clickable にする発想は持ち込まない方が安全です。⌨️
Badge を押せる UI にしたいなら、Badge 自体をボタン化するより、親コンポーネント側を操作対象にし、Badge は状態表示に徹する方が v5 の方向性に合っています。
2. アイコンだけの Badge は代替テキストが必要
Fluent UI 2 では、icon-only badge は aria-label が必要です。Blazor 5 側でも同様に、アイコンを使うなら IconLabel で代替テキストを与える必要があります。🔊
<FluentBadge IconStart="@(new Icons.Regular.Size16.Globe())"
IconLabel="公開中を示す地球アイコン" />
3. Badge の意味は親コンポーネント側でも伝える
Fluent UI 2 では、Badge が別のコンポーネントに紐づくなら、そのコンポーネントの aria label に Badge の意味も含めるべきだとされています。Blazor 5 側でも、badge text だけでは不十分なときは parent 側に explicit label を持たせることが推奨されています。
たとえば、「Blocked」という Badge が付いたカードなら、カードやリンクのアクセシブルネーム側で「Blocked item」「対応が必要な項目」など、状態が文脈として伝わるようにするのがよいです。
4. 色だけに頼らない
これは Badge で特に起きやすい問題です。warning を黄色、danger を赤で見せても、色覚差や画面条件によっては意味が落ちます。そのため、テキスト・アイコン・周辺ラベルを組み合わせて意味を補う必要があります。🟡🔴
つまり Badge のアクセシビリティは、単体の属性よりも文脈設計の方が効きます。次は、v4 と v5 の差を整理します。🔍
Fluent UI Blazor 4 と 5 はかなり違う 🔥
ここは本当に大事です。Fluent UI Blazor 4 の FluentBadge と、Fluent UI Blazor 5 の FluentBadge は、同じ名前でもかなり別物です。
v4 側の特徴
v4 系の FluentBadge では、次のようなパラメーターがありました。
-
ChildContentを badge text として使う -
Fill(string) -
Circular(bool) -
Width/Height OnClick-
DismissIcon/DismissTitle/OnDismissClick -
AppearanceはAccent/Neutral/Lightweight
v5 側の特徴
v5 では、次のように変わっています。
-
Contentが badge text 用に追加 -
AnchorContentで関連コンテンツをラップできる -
ColorはBadgeColorenum -
AppearanceはBadgeAppearanceenum (Filled/Ghost/Outline/Tint) -
Shapeで形状を指定 -
Sizeでサイズを指定 -
Positioning、OffsetX、OffsetYで attached badge を調整できる -
OnClickが削除 -
Dismiss*系も削除 -
Width/Heightは使わず、サイズ体系へ寄せる
比較すると次のようになります。
| 項目 | v4 | v5 |
|---|---|---|
| 📝 バッジ文字列 | ChildContent |
Content |
| 🎨 色 |
Fill 文字列中心 |
BadgeColor enum / BackgroundColor
|
| 🔵 形状 | Circular |
Shape |
| 📏 サイズ |
Width / Height
|
Size |
| 🖱️ クリック |
OnClick あり |
削除 |
| ❌ dismiss |
Dismiss* あり |
削除 |
| 📍 配置 | 単体寄り |
AnchorContent で attached badge を明示 |
| 🪄 appearance |
Accent / Neutral / Lightweight
|
Filled / Ghost / Outline / Tint
|
古いブログ記事やサンプルで OnClick や Fill、Circular を見かけたら、それは v4 前提の可能性が高いです。Badge を調べるときは、最初に v4 なのか v5 なのかを確認した方が安全です。
私自身、Blazor コンポーネントは名前が同じでも意味が変わることがあるので、この章を最初に見返せるようにしておくと事故が減ると感じています。🧠
Fluent UI Blazor 5 での実装イメージ
最後に、Badge を v5 でどう使うかを最小限で並べます。ここでは Badge を中心にしています。
基本の Badge
<FluentBadge Content="Beta"
Appearance="BadgeAppearance.Tint"
Color="BadgeColor.Brand" />
輪郭線で軽めに見せる
<FluentBadge Content="Draft"
Appearance="BadgeAppearance.Outline"
Color="BadgeColor.Subtle" />
attached badge として使う
<FluentBadge Content="New"
Appearance="BadgeAppearance.Filled"
Color="BadgeColor.Brand">
<AnchorContent>
<FluentButton Appearance="Appearance.Outline"
aria-label="通知、New バッジ付き">
通知
</FluentButton>
</AnchorContent>
</FluentBadge>
カスタム色を使う
<FluentBadge Content="Preview"
Appearance="BadgeAppearance.Filled"
BackgroundColor="#5C2D91" />
実装としてはシンプルですが、設計判断は意外と深いです。何を伝えるのか、どこに置くのか、色に意味を持たせるのか、親要素側でどう読ませるのかまで考えてはじめて、Badge はきれいに機能します。✨
まとめ 🎉
Fluent UI 2 の Badge は、関連コンポーネントの状態や説明を補助的に伝える visual indicator として設計されています。短い言葉、意図ある色、近い配置、そして文脈込みのアクセシビリティがポイントです。📌
一方で Fluent UI Blazor 5 では、その考え方がより明確な API に分解されています。特に次の点を押さえると迷いにくいです。
- ✅
Badge/CounterBadge/PresenceBadgeは分かれている - ✅ text badge の中心は
Content - ✅ attached badge は
AnchorContentとPositioningで表現する - ✅ 色は
BadgeColorとBackgroundColorを使い分ける - ✅ 長文や truncation はライブラリ任せにしない
- ✅ Badge 自体をインタラクティブにする発想は v5 では弱い
- ✅ v4 の
OnClick/Fill/Circular前提を持ち込まない
Badge は小さなコンポーネントですが、情報設計・アクセシビリティ・ライブラリ移行の話がかなり詰まっています。だからこそ、Fluent UI 2 の設計ガイドと Blazor 5 の API を分けて理解しておくと、実装がとても安定します。🚀