通知センターシステム
目的
通知センターシステムは、アプリ内通知センター、フィード、またはインボックスのための構造化された再利用可能な設計フレームワークを提供します。最新のウェブアプリケーション、特にSaaSワークスペース、コミュニティポータル、コラボレーションエディタ、eコマースアカウントでは、通知によりユーザーは非同期イベント(例:メンション、コメント、システムアラート、ワークフローステータス更新、タスク完了)について最新情報を入手できます。
専用の通知センターがない場合、アプリケーションは侵入的なオーバーレイ(モーダル)や過渡的で見逃しやすい通知(トースト/バナー)に頼らざるを得ません。このシステムはこれらの更新を一元化し、視覚的階層、インタラクティブな状態(既読と未読)、コンテキストによるグループ化、レスポンシブ適応を管理すると同時に、完全なキーボードとスクリーンリーダーのアクセシビリティ(WCAG AA)を保証します。
ユースケース
- コラボレーションワークスペース: ドキュメントコメント、共有フォルダ、タスク割り当て、メンションの集約(例:Slack、Notion、Figma)。
- 非同期ワークフロー: データエクスポート、バックグラウンドレポート、ビルドデプロイメント、バッチ処理などの長時間実行操作の追跡。
- トランザクション更新: eコマースの配送状況、サブスクリプション更新リマインダー、支払い確認の追跡。
- ソーシャル&コミュニティフィード: 「いいね!」、返信、フォロー、グループ招待、アクティビティ更新の管理。
- アカウントセキュリティと健全性: 新しいログイン場所、パスワード変更、ストレージクォータ警告についてユーザーに通知。
使用すべきでない場合
- クリティカルブロッカー: イベントがユーザーの現在のタスクの完了を妨げなければならない場合(例:支払い失敗、セッション期限切れ、無効なデータ送信)は、
overlay-and-dialog-system(モーダル/アラートダイアログ)を使用してください。 - 過渡的な単一タスクフィードバック: 直接的なアクションの即時確認(例:「リンクをコピーしました」「設定を保存しました」)には、トーストを使用してください(
toast-and-snackbar-systemを参照)。 - グローバルダウンタイム告知: サイト全体の優先度の高いシステムアラート(例:「30分後に定期メンテナンスを実施します」)には、グローバルバナーを使用してください(
banner-and-alert-systemを参照)。 - スタンドアロンコンバージョンランディングページ: スタンドアロンランディングページは外部リンクと気を散らす要素を最小限に抑える必要があります。グローバルな通知アイコンは逆効果です。
入力
- 情報アーキテクチャ(通知スキーマ):
- メタデータ: 作成者のアバター/イニシャル、イベントソース、アクションタイプ。
- コンテンツ: タイトル(何が起こったか)、本文(追加の詳細/コンテキスト)、タイムスタンプ。
- 状態: 既読と未読、高/中/低優先度、アーカイブ済み。
- アクション: プライマリターゲットリンク、インラインクイックアクション(例:「承認」「既読にする」「スレッドをミュート」)。
- 表示コンテキストと密度: インターフェースは高密度のSaaSダッシュボード(省スペースなポップオーバーリストアイテムが必要)ですか、それとも広々としたプラットフォーム(スライドアウトドロワーやページを利用可能)ですか?
- トリガーアイコン: 視覚的なアンカー(通常はベルのアイコン)と通知バッジのデザイン(数値カウントと単純なドットインジケーター)。
- インタラクティブアクションレイアウト: 利用可能な一括アクション(例:「すべて既読にする」「すべてクリア」「通知設定」)。
出力
- トリガーバッジの構造: ヘッダーアイコン、数値バッジカウント、サイレントインジケータードットの具体的な設計基準。
- コンテナレイアウト仕様: サイズ、境界、配置、コンテナの動作(ドロップダウン、サイドドロワー、または専用ページ)。
- 通知カードの構造: 明示的な内部レイアウト(アバター、本文、タイムスタンプ、未読インジケータードット、クイックアクショントリガー)。
- 状態遷移マトリックス: 未読と既読の状態、ホバー状態、アクティブ状態、フォーカスリング、ローディングスケルトンのための明確なスタイリング。
- キーボードとスクリーンリーダーの仕様: フォーカストラップパラメータ、ロービングタブインデックス構造、ライブリージョンアナウンス定義、カスタムaria説明。
ワークフロー
1. ヘッダートリガーとバッジインジケーターの設計
通知センターのエントリポイントは、ほぼ常にグローバルユーティリティヘッダー(右側)にあります。
- ベルのアイコン: クリーンなベルのアイコンを選択します。
- 未読カウントバッジ:
- ベルのアイコンの右上の象限に円形のバッジを配置します。
- コンテナのオーバーフローを防ぐために、バッジカウントを
99+(または非常に狭いレイアウトでは9+)に制限します。 - カウントが0の場合、バッジはDOMから削除するか、
display: noneを使用して非表示にする必要があります(赤いバブルの内側に0を表示しないでください)。 - 未読通知の数を明示的に示す
aria-labelまたは非表示のスクリーンリーダーテキストを含めます(例:<span class="sr-only">、4件の未読通知</span>)。
2. コンテナレイアウトパターンの選択
密度、ターゲットデバイス、必要なインタラクションの量に基づいてレイアウトを選択します。
- パターンA: ドロップダウンポップオーバー(中程度のコンテンツ密度のデスクトップデフォルト)
- トリガーに対して相対的に配置されます。
- 推奨寸法: 最小幅
320px、最大幅420px。高さは500pxに制限され、スクロール可能なコンテナ(overflow-y: auto)を使用します。 - 標準のポップオーバーメカニズム(またはネイティブPopover API)を使用してポップアップをアンカーし、最上位のスタッキングコンテキストに表示されるようにします。
- パターンB: サイドドロワー(高コンテンツ密度または複雑なアクションフローに最適)
- 画面の右端からスライドインし、ビューポートの全高を占めます。
- 推奨幅:
360pxから480px。 - 微妙な背景オーバーレイ(スリム)でページ背景を暗くします。
- パターンC: 専用通知ページ(モバイルビューポートまたは複雑なインボックス管理のフォールバック)
- 詳細な通知アーカイブの並べ替え、検索、フィルタリング、一括管理に適した全画面表示です。
3. 内部カード階層と構造の確立
個々の通知はカードです(<ol>または<ul>内のリストアイテム<li>)。厳密な垂直および水平グリッド階層に従う必要があります。
+-------------------------------------------------------------+
| (•) [アバター] **山田太郎** さんが _プロジェクトX_ であなたをメンションしました (x) |
| 「改訂されたUIスケッチを確認してください。」 |
| [ 3時間前 ] [ 承認 ] [ 辞退 ] |
+-------------------------------------------------------------+
- 未読インジケータードット(水平アンカー): 小さく、コントラストが高く、プライマリカラーのドット(例:青または紫)を左端に配置します。これは未読アイテムを最も速くスキャンするためのアンカーです。
- アバター/アイコンエリア: インジケーターの隣に、ユーザー生成イベントの場合は円形のアバターを、システムイベントの場合は色付きの背景を持つカテゴリ化されたユーティリティアイコンを配置します。
- テキストブロック(垂直フロー):
- タイトル/ヘッダー: アクターとアクションを強調する太字テキスト。
- 抜粋: セカンダリコンテンツ(例:コメントテキスト、エラーの説明)を示す、より小さくミュートされたテキスト。CSSのline-clampで最大2行に制限します。
- タイムスタンプ: 相対時間を示す、ミュートされた小さなテキスト(例:
12px)(例:「5分前」「昨日」)。
- クイックアクション(コンテキストトリガー):
- テキスト抜粋の下に配置されたクイックアクションボタン(例:「招待を承諾」「コメントを表示」)。
- ホバー/フォーカス時に、右隅に微妙なセカンダリトリガー(例:オーバーフローメニューボタン、または直接の「既読にする」チェックマークボタン)を提供します。
- 閉じる/閉じるアイコン(X)は右上隅に配置し、タッチインタラクションのために少なくとも
24x24pxのサイズにします。
4. 明確な状態遷移の作成
ユーザーインタラクションを反映するために、明確な状態を提供します。
- 未読状態: 明るい背景、太字テキスト、表示された青いインジケータードット。
- 既読状態: 未読の背景をフェードアウトし、テキストの太さを標準に変更し、インジケータードットを非表示にします。
- ホバー/フォーカス状態: 背景色をわずかにシフトし(例:白からソフトなニュートラルグレーへ)、セカンダリインライントリガー(例:「アーカイブ」「既読にする」)を表示します。
- フォーカス状態: キーボードでナビゲートされた場合、個々のアイテムの周りに高コントラストのフォーカスリング。フォーカスを可視でシャープに保ちます(オフセット付きの最小2pxのアウトライン)。
- 無効状態: アクションカードが処理中の場合(例:「承認」をクリック)、インラインのローディングスピナーを適用し、不透明度を
0.5に下げ、ボタン属性をdisabledに設定してダブルクリックを防ぎます。
5. 一括操作と空の状態の定義
- フッターナビゲーション: 常に「すべての通知を表示」(専用ページへのリンク)または「すべて既読にする」へのフッターリンクを提供します。
- 空の状態: 通知がない場合、またはすべての通知がクリアされた場合、励ましのビジュアル(例:チェックマークやベル)、ニュートラルなヘッダー(「すべて確認済み!」)、および「通知設定」へのセカンダリ記述リンクを含む空の状態を表示します(
empty-state-systemを参照)。
6. キーボードフォーカスとスクリーンリーダー管理の実装
- トリガートグル: ベルのアイコンで
EnterまたはSpaceを押すと、ポップオーバーが切り替わります。aria-expanded="true/false"とaria-controls="notification-panel-id"を適用します。 - フォーカストラップ(ドロワーとポップオーバー用): 開かれると、キーボードフォーカスはすぐにパネル内の最初のアクション可能な要素(通常は「すべて既読にする」ボタンまたは最初の通知アイテム)に移動する必要があります。パネルが表示されている間、フォーカスはパネル内に閉じ込められる必要があります。
Escapeを押すとパネルが閉じ、フォーカスがベルのアイコンに直接戻る必要があります。 - ロービングタブインデックス/リストナビゲーション: 数十の通知アイテムがある場合、キーボードユーザーが
ArrowUpとArrowDownキーを使用してカード間を移動できるようにし、アクティブなアイテムにはtabindex="0"、その他にはtabindex="-1"を設定して単一のタブストップを維持します。これにより、キーボードユーザーがページの最後に到達するために50のリンクをタブ移動する必要がなくなります。 - スクリーンリーダーアナウンス: 非表示の
aria-live="polite"リージョンを使用して、未読カウントへの動的な更新をアナウンスします(例:「Sarahからの新しい通知があります」)。
決定ルール
ルール1: ドロップダウン vs サイドドロワー vs ページ
このレイアウトグリッドを使用してコンテナ構造を選択します。
- ドロップダウンポップオーバーを選択する場合: アプリの平均的な通知数が10〜15件未満で、ほとんどが短い更新であり、アクションが単純な場合(直接リンクやクイック閉じるなど)。
- サイドドロワーを選択する場合: 通知パネルにインタラクティブなタブ(例:「すべて」「メンション」「アーカイブ」)が含まれている場合、リッチなマルチラインカードの概要が必要な場合、または通知内で直接返信するためのテキスト入力などの複雑なフォームフィールドが必要な場合。
- 専用ページを選択する場合: ユーザーが通知負荷の高いワークロード(例:GitHub PRレビューインボックス、Zendeskサポートチケット、Shopifyストアアラート)を管理しており、堅牢な検索フィルター、チェックマークの複数選択、大規模なアーカイブワークフローが必要な場合。
ルール2: アバター vs アイコンインジケーター
- ユーザーアバター(画像またはイニシャル)を使用する場合: 通知が特定の人間によってトリガーされたソーシャルまたは直接のコラボレーションイベントである場合(例:「Sarahがファイルを共有しました」)。
- システムアイコン(ステータス固有の色:アラートは赤、警告は黄、情報は青)を使用する場合: イベントがシステム生成の場合(例:「データベースバックアップが完了しました」)。
ルール3: 既読アクションの動作
- 通知カードをクリックすると、ユーザーをディープリンクターゲットにリダイレクトし、かつアイテムを既読としてマークする必要があります。
- カードに専用の表示可能な「既読にする」チェックマークアイコンを提供し、ユーザーがパネルから移動せずにアイテムを既読としてマークできるようにします。
制約
1. コントラストとサイズ(WCAG AA)
- テキストコントラスト: すべての通知コピーが
4.5:1のコントラスト比を満たしていることを確認します。タイムスタンプとミュートされた抜粋は4.5:1(または大きなテキストの場合は3:1)を下回ってはなりません。 - タッチターゲット: 個々のボタン(閉じるアイコン、承認/辞退リンク、既読にするチェックマーク)のタップターゲットは、WCAG 2.2 SC 2.5.8の最小ターゲットサイズである
24x24pxを満たしている必要があります。 - キーボードコントラスト: フォーカスリングは、カードの背景に対して最小コントラスト比
3:1を持つ必要があります。
2. レスポンシブネス
- デスクトップ: フローティングパネルはインテリジェントに配置する必要があります。トリガーが画面の右端の近くにある場合、ポップオーバーはクリッピングを防ぐために右側に揃える必要があります。
- モバイルビューポート(
< 768px): デスクトップのドロップダウンポップオーバーを全画面パネルまたは下部に揃えたスライドアップシートに変換して、親指のリーチアクセシビリティを確保し、小さくスクロールできないポップオーバーコンテナを防ぎます。
3. 動的スタッキング
- ポップオーバーまたはドロワーのz-indexが標準のレイアウト要素の上に、しかしモーダルトリガーの下に設定されていることを確認します(例:
--z-index-popover: 1000、--z-index-modal: 2000)。
一般的な失敗パターン
- 「脱出不可能なインボックス」: デスクトップでドロップダウン通知ポップオーバーを開いたが、
Escapeキーのクローズリスナーを提供しなかった。ユーザーは小さな「X」を見つけてクリックするか、外側をクリックして閉じることを余儀なくされます。 - 「バッジが消えない」ループ: 未読アイテム
3を表示する通知バッジがあるが、パネルを開いてもどのカードが未読かが視覚的に強調表示されておらず、それらを既読としてマークする明確な方法も提供されていない。バッジはそのまま残り、ユーザーの疲労とバナー盲につながります。 - 「シンク流し」フィード: メールの全文、生のデータベースログ、マーケティングプロモーションを小さなドロップダウンパネルに詰め込み、レイアウトのオーバーフローと視覚的階層の崩壊を引き起こします。
- スクロール時のレイアウトシフト: 静的ピクセル座標でスタイル設定されたポップオーバーが、スクロール時にヘッダーのベルのアイコンに固定されず、コンテンツ上をランダムに浮遊します。
- 二重フォーカスアウトライン: 外側のコンテナカードと内部のディープリンクボタンの両方が同時にフォーカスをキャプチャし、キーボードユーザーが通知ごとに2回タブ移動する必要がある二重層のフォーカススタイリング。
検証基準
- バッジカウントの動作: 未読カウントが
0の場合、赤いドットまたは数値インジケーターが完全に非表示になります。 - 状態のコントラスト: 未読カードは、既読カードと明確に視覚的に区別されます(背景、テキストの太さ、インジケータードットを使用)。
- ターゲットサイズ: カード内のすべてのクリック可能なボタン/リンクがWCAG 2.2の24x24pxのタッチターゲット最小値を満たしています。
- レスポンシブ変換: モバイルでは、デスクトップのポップオーバーが全画面または下部シートに変換されます。