トースト&スナックバーシステム は何をしますか?
目的
トースト&スナックバーシステムは、一時的で非破壊的な通知レイヤーを設計するための方法論を提供します。これらは、プライマリインターフェースの上の専用画面レイヤーに配置される、短時間表示されるか手動で閉じることができるUIコンポーネントです。モーダルオーバーレイとは異なり、フォーカスを奪ったりユーザーのフローを止めたりしません。代わりに、バックグラウンドまたは即時のタスクが成功したか、失敗したか、軽微な注意が必要かを確認する、受動的かつ視認性の高い「確認ループ」として機能します。このシステムは、トーストが視覚的に統一され、重要なコントロールを妨げない位置に配置され、マウス、タッチ、支援技術のユーザーが完全にアクセスできることを保証します。
ユースケース
- 非同期アクション: ファイルのアップロード、下書きの保存、レコードの削除がバックグラウンドで完了したことを確認する。
- マイクロコミットの確認: カートへの商品追加、クリップボードへのリンクコピー、ローカルシステム設定の切り替えなどのアクションを確認する。
- 元に戻せる破壊的操作: アイテムがアーカイブまたは削除されたことを通知し、スナックバー内に即座に「元に戻す」アクションを提供する。
- 一時的なステータス更新: 「オフライン」または「オンライン」状態への移行など、短時間の自動システムアラートを表示する。
使用すべきでない場合
- 重大なシステムブロック: 緊急の介入が必要な重大なエラーやユーザーの進行を妨げる場合(例:セッション期限切れ、支払い失敗)は、
overlay-and-dialog-system(モーダル)を使用する。 - 永続的なセクション警告: セクション、ページ、フォームコンテキスト全体に関連する警告やエラーで、解決まで表示を維持する必要がある場合は、
banner-and-alert-system(インラインアラート)を使用する。 - フォームバリデーションメッセージ: 特定の入力フィールドでユーザーがエラーを起こした場合は、
form-design-system(フィールドレベルのバリデーション)を使用する。 - プライマリコンテンツの発見: トーストをプライマリコンテンツ、マーケティング告知、ナビゲーションオプションの提示に決して使用しない。
入力
- メッセージの重要度/タイプ: 成功(確認)、情報(中立的な更新)、警告(非ブロッキングな懸念)、またはエラー(操作の失敗)。
- アクション要件: フィードバックは受動的(読み取り専用)か、単一のマイクロアクション(例:「元に戻す」、「表示」、「再試行」)を含むか。
- 画面領域とデバイスクラス: ターゲットとするビューポート(デスクトップ、タブレット、モバイル)と主な入力方法(マウスホバー vs 親指のリーチ)。
- Zインデックスとレイヤリング戦略: ヘッダーナビゲーション、スティッキーフッター、アクティブなオーバーレイとの重なりを防ぐためのスタッキングコンテキストルール。
出力
- 構成要素の仕様: コンテナ、アイコンスロット、メッセージ文字列、アクションCTA、手動閉じるボタンのグリッドベースの設計図。
- 空間配置と配置ルール: デスクトップ用(例:右上または右下スタック)およびモバイル用(例:下部全幅スライドアップ)の適応座標。
- キューとスタッキングロジック: 同時アラートの処理、最大表示制限、有効期限シーケンスのシステムルール。
- インタラクティブタイムラインと有効期限仕様: 自己消滅タイムアウト、ホバーで一時停止、スワイプジェスチャのルール。
- アクセシビリティ/ARIA設計図: ライブリージョンのセマンティックマッピング、インタラクティブなトーストのフォーカス処理、スクリーンリーダーによるアナウンス。
ワークフロー
1. コンポーネントの構成要素を構造化する
標準のスペーストークンを使用して、トーストコンテナの正確な間隔とレイアウトグリッドを定義する。
- アイコンスロット: 固定幅(例:20pxまたは24px)で左端に配置。セマンティックで高コントラストなステータスアイコン(成功はチェックマーク、警告/エラーは感嘆符付き三角形、情報は情報アイコン)を使用する。
- テキストエリア: 左揃えで折り返し可能なタイポグラフィ。簡潔なタイトル(太字、任意)と説明文で構成する。テキストを省略記号で切り詰めず、最大3行まで折り返す。
- アクションスロット(オプション): メッセージの右側に配置する、視認性の高い単一のテキストボタン(例:「元に戻す」)。モバイルでテキストが長い場合は、アクションを新しい行に折り返し、右揃えにする。
- 却下トリガー: 右端に配置する明確な「X」閉じるボタン。最小24x24pxのヒット領域が必要(タッチターゲットとしては44x44px推奨)。
2. ビューポートに応じた空間配置を決定する
- デスクトップ配置: トーストコンテナスタックを画面の右上または右下に配置する。ビューポート端からは一貫して
24pxのオフセットを保つ。- 右上スタック: プライマリ操作がページの下部で行われる場合に最適。
- 右下スタック: 上部にナビゲーションやユーティリティバーがあり、重なりを防ぐ場合に最適。
- モバイル配置: デスクトップスタックを、下部に固定された全幅のスナックバー(左、右、下端から
12pxから16pxのマージン)に変換する。これにより、操作が最適な「親指のリーチゾーン」に収まる。 - Zインデックスのルール: トーストに専用のz-indexトークン(例:
z-index: 5000以上)を常に割り当て、標準のスティッキーヘッダー(z-index: 1000)より上だが、アクティブな全画面オーバーレイ(z-index: 10000)より下に配置する。
3. スタッキングとキューイングのロジックを確立する
レイアウトの乱れや認識過多を引き起こさずに、高頻度のトリガー環境を管理する。
- 最大表示制限: アクティブなキューを最大3つのトーストを垂直に積み重ねたものに制限する。
- スタッキング方向:
- 画面の上部に配置する場合、新しいトーストは上からスライドインし、古いトーストを下に押し出す。
- 画面の下部に配置する場合、新しいトーストは下からスライドアップし、古いトーストを上に押し出す。
- キューイングバッファ: 3つがアクティブな状態で4つ目のトーストがトリガーされた場合、新しいトーストをメモリにバッファリングする。最も古いトーストが自然に期限切れとなりフェードアウトしたら、すぐにレンダリングする。
4. 有効期限とホバーで一時停止のタイムラインをコード化する
トーストは読むのに十分な時間存在しつつ、画面をクリアするために迅速に消える必要がある。
- 動的Time-to-Live(TTL): コンテンツの長さに基づいて有効期限を計算する。
- 短い受動的トースト(40文字未満): 5秒後に消去する。
- 長いトーストまたはアクション付きトースト: 7~10秒後に消去し、スクリーンリーダーが完全にアナウンスし、ユーザーが読んで行動する時間を確保する。
- エラー/失敗トースト: 自動消去しない。ユーザーが手動で「X」ボタンをクリックするまで表示を維持し、重要なフィードバックが失われないようにする。
- 「ホバーで一時停止」インタラクション:
- マウスユーザーがトーストキューの任意の部分にホバーした場合、すべてのアクティブなTTLカウントダウンを一時停止する。マウスがトーストの境界を離れたときにのみ、タイマーをリセットして再開する。
- キーボードユーザーがトースト内の任意の要素にフォーカスした場合、タイマーを無期限に一時停止する。フォーカスがメインドキュメントに戻ったときにのみ、カウントダウンを再開する。
5. 閉じるとジェスチャの動作を定義する
- タッチスワイプ: モバイルデバイスでは、ユーザーが個々のスナックバーを水平方向に(左または右に)スワイプして即座に却下できるようにする。ドラッグのしきい値はビューポート幅の30%に保つ。
- アニメーション: スムーズでハードウェアアクセラレーションされたトランジション(例:
transformとopacity)を、持続時間200msから300ms、cubic-bezier(0.16, 1, 0.3, 1)(ease-out-expo)で入場に使用し、退場には単純なopacityフェードアウトを使用する。
決定ルール
スタッキング配置マトリックス
| ビューポート | プライマリナビゲーションレイアウト | 推奨トースト配置 | アニメーション方向 |
|---|---|---|---|
| デスクトップ | 左サイドバー/ダッシュボード | 右下(メイン作業をクリアに保つ) | 画面外から左にスライド |
| デスクトップ | スティッキートップヘッダー | 右下(ナビの隠蔽を防ぐ) | 左または上にスライド |
| デスクトップ | ミニマリスト/フッター重視 | 右上 | 左または下にスライド |
| モバイル | 任意 | 下部中央/全幅 | 下端から上にスライド |
有効期限ロジックマトリックス
| トーストの重要度/タイプ | アクションボタンを含む? | 推奨有効期限 | 却下タイプ |
|---|---|---|---|
| 成功/情報 | いいえ | 5秒(固定) | 自動消去+手動クローズ |
| 成功/情報 | はい(「元に戻す」/「表示」) | 8~10秒 | 自動消去+手動クローズ |
| 警告 | いいえ | 7秒 | 自動消去+手動クローズ |
| エラー/失敗 | はいまたはいいえ | 無限(永続的に表示) | 手動クローズのみ |
制約
- アクセシビリティ(WCAG 2.2準拠):
- ARIAライブリージョン: 受動的なトーストは
role="status"(デフォルトでaria-live="polite"およびaria-atomic="true")にマッピングする。システム障害(例:「インターネット接続が失われました」)を伝える場合を除き、role="alert"(アサーティブ)の使用は避ける。アサーティブアラートはスクリーンリーダーの読み上げを即座に中断するため。 - キーボードによる道案内(WCAG 2.2 SC 2.1.1): トーストにインタラクティブなアクション(例:「元に戻す」や「表示」)が含まれる場合、キーボードでアクセス可能でなければならない。キーボードのタブループは遅い可能性があるため、グローバルなバイパスショートカット(例:
Escapeでアクティブなトーストを閉じる、F6でフォーカスをトーストキューコンテナに直接移動する)を提供するか、DOMタブ順序でトーストコンテナをアクティブトリガーの直後に配置する。 - フォーカストラップなし: トーストキュー内にキーボードフォーカスを閉じ込めない。ユーザーはトーストから自由にタブアウトしてページコンテンツに戻れる必要がある。
- ARIAライブリージョン: 受動的なトーストは
- コントラスト(WCAG 2.2 SC 1.4.3):
- すべてのテキスト、ステータスアイコン、ボタンは、トーストの背景に対してコントラストの最小値を満たす必要がある。
- 通常のテキスト:4.5:1 最小コントラスト。
- アイコンとアクティブなコントロールの境界線:3:1 最小コントラスト。
- すべてのテキスト、ステータスアイコン、ボタンは、トーストの背景に対してコントラストの最小値を満たす必要がある。
- レスポンシブ性:
- ビューポートが
< 600pxの場合、トーストコンテナは全幅(width: calc(100% - 32px))で中央揃えにし、不自然なマージンカラムを防ぐ。
- ビューポートが
よくある失敗パターン
- 「アクションの隠蔽」トラップ: デスクトップのトーストキューを、ショッピングカートのヘッダーボタンやテーブルフィルタードロップダウンなど、高頻度のインタラクティブ要素の真上に配置し、ユーザーが誤クリックする原因となる。
- 「見えたかと思ったら消えた」フラッシュ: 複雑で長いエラーや警告を2〜3秒で自動消去する。これは基本的なアクセシビリティの読み取りしきい値に違反し、コンテキストを見逃したユーザーをパニックに陥れる。
- スクリーンリーダーの無言: ARIAライブリージョンラッパーなしでトーストを動的にDOMに追加し、視覚障害ユーザーから完全に見えなくする。
- レイアウトシフトの乱れ: トーストキューの高さを突然アニメーションさせ、メインページコンテンツを上下にシフトさせる。
- ホバー/フォーカス有効期限の無視: ユーザーが密度の高いテキストメッセージをホバーリーディング中、または「元に戻す」CTAにホバー中にトーストを自己消去させ、ユーザーが「無効領域」をクリックして意図しないアクションをトリガーする原因となる。
検証基準
- トーストは、明確で高コントラストなセマンティックインジケータ(色+一意のアイコン)でスタイル設定されている。
- デスクトップでは、トーストがプライマリナビゲーション要素やグローバルアクションゾーンに重ならない。
- モバイルでは、トーストが下部固定の全幅コンポーネントに変換され、親指で簡単に到達できる。
- アクティブなタイマーは、マウスでホバーされるかキーボードでフォーカスされたときに即座に一時停止する。
- アクション付きトーストは最低8~10秒間表示され、エラートーストは自動消去しない。
- セマンティックなスクリーンリーダーマークアップ(
role="status"またはrole="alert")が正しく指定されている。 - キーボードユーザーはフォーカストラップの障壁なくトーストのアクションボタンに移動してトリガーできる。
- すべてのインタラクティブ要素(閉じるボタン、CTA)がWCAG 2.2の24x24px最小タッチターゲット(44x44px推奨)を満たしている。