知らせる
知らせ方の分岐は1つです。消えてよい情報か、残しておくべき情報か。失敗は、いつでも残す側です。
図の中身を文字で読む
- 消える トースト・スナックバー 残る アラートバナー
- 下書きを保存しました 3件の項目にご確認いただきたい点があります
- メールアドレス
- 電話番号
- 1件をアーカイブしました 取り消す
- ✕ エラーをトーストで出す
- 成功の通知・見落としても支障がないもの
- 操作を1つ含められるのがスナックバー。
- 「確認してから実行」を「実行してから取り消せる」に置き換えると、正しい操作のときの摩擦が消える。
- 消えると、失敗に気づけないまま進んでしまう。
- 対応が必要な情報は残す。参考情報は閉じられるようにする。
- 動的に出すなら、ライブリージョンとして宣言しないと読み上げに届かない。
- 読み込み中に何を出すか
- 300ms未満=何も出さない / 1〜3秒=スケルトン(構造を見せる) / それ以上=進捗表示(見通しを示す)
ひと目で#
- トースト
- 隅にしばらく出て、自動で消える。操作を含まない
- スナックバー
- トーストに操作を1つ含められる。取り消しの導線に使う
- アラートバナー
- 流れの中に置かれ、自動では消えない
- バッジ
- 件数や状態を示す小さな印。押せない
- チップ
- 押せる、または消せる小さな要素。絞り込みの条件を表す
- ライブリージョン
- 動的な変化を読み上げに伝える仕組み
使い分け#
| 伝えたいこと | 使うもの |
|---|---|
| 保存した、コピーした | トースト |
| 削除した(取り消せる) | スナックバーに「取り消す」 |
| 失敗した。対応が要る | アラートバナー。消さない |
| 返事を求める | ダイアログ |
| 未読が3件ある | バッジ |
| かかっている絞り込みの条件 | チップ。1つずつ外せる |
図の中身を文字で読む
- 待たせる長さで、出すものが変わる
- 待ち時間
- 300ms 未満
- 何も出さない
- 出しても一瞬で消え、ちらつきとして残るだけ
- 1〜3秒
- スケルトン
- これから出る形を先にかたどる
- それ以上
- 進捗表示
- あとどれくらいかの見通しを示す
- 3件中 2件を送信しました
- 結果をそのまま描く 寸法は実物と合わせる 量が分かる処理は確定型で
- 寸法が実物とずれたスケルトンは、切り替わった瞬間に行がずれる。骨組みを見せる意味が消える。
| 待ち時間 | 出すもの |
|---|---|
| 300ms 未満 | 何も出さない。ちらつきになる |
| 1〜3秒 | スケルトンスクリーン。構造の形を先に見せる |
| それ以上 | 進捗表示。見通しを示す |
| 全体の量が分かる処理 | 確定型の進捗バー |
間違えやすいところ#
- エラーをトーストで出す消えたら、失敗に気づけない
- ライブリージョンとして宣言しない目には見えても、読み上げに届かない
- トーストを何枚も積み上げる読み切れない
- 取り消せないのに「取り消す」を出す信頼を失う
- 表示時間を一律にする文言が長いと読み切れない
- スケルトンの寸法を実物と合わせない結局レイアウトがずれる
- 押せないバッジを押せそうな見た目にする誤操作を招く
- 二重送信を防がない同じ処理が何度も走る
直す例#
架空の案件を1つ例にとります。どこを見て、何をどう直すかを書きます。
予約管理画面で、保存の成功も失敗も同じトーストで3秒だけ出ます。画面から目を離していた店主は失敗に気づかず、入力したはずの予約が消えたという問い合わせになりました。
成功と失敗で通知の寿命を分けます。成功は消えるトーストのまま、失敗は自動では消えないアラートバナーに変え、原因と再試行の導線を添えます。読み上げには role="alert" の空の枠をあらかじめ置いておき、失敗時は中身だけを差し替えます。要素ごとあとから挿入すると、画面には見えても読み上げが拾わないことがあります。
確認する#
- 失敗の知らせは自動で消えない。消えるのは成功だけ
- 通知の枠が最初から DOM にあり、中身の差し替えで読み上げに届く
- 取り消せない操作に「取り消す」を出していない。二重送信はボタンの無効化で止まる
使えるパターン#
このページで扱う語#
このページで扱う語を並べる本文では太字3 語
語の名前から引くなら用語索引へ。
- プログレスインジケーター
- 処理がどこまで進んだかを視覚的に示す部品。完了までの見通しを与える。
- スピナー
- 回転するアニメーションで処理中であることを示す表示。完了までの見通しは示さない。
- スケルトンスクリーン
- 読み込み中に、これから表示される内容の形を灰色の矩形で示す表示方式。
この話が要る場面#
このページが答えになる、現場の困り事です。困り事の側から探すと、同じ場所に着きます。
気づかなくてよいものは控えめに出し、操作を止めるべきものだけ読み上げにも割り込ませる。
このコードで動いている見本です
読む時間+2秒。消えると困る情報はトーストに載せない。
このコードで動いている見本です
処理中の表示と、完了の表示を分けて出す。押した直後にボタンを無効化して二重送信を防ぐ。
btn.disabled = true;
btn.textContent = '送信中…';
// 完了後 → btn.textContent = '送信完了';この場面のほかの困り事と、そのまま貼れる部品は部品を選ぶ、フォームを作るにまとめてある。逆引きには全188件。
知らせを試す#
3つのボタンが、見た目のアラート面と読み上げ用のライブリージョンを同時に動かします。スクリーンリーダーを立ち上げておくと、polite と assertive の割り込み方の違いも聞き比べられます。
読み上げ用の枠は、空のまま先に置いてあります。あとから要素ごと足すと、読み上げが拾わないことがあるためです。
<!-- 空の枠を先に置く。あとから要素ごと足すと、読み上げが拾わないことがある -->
<div role="status" class="visually-hidden" id="live-status"></div>
<div role="alert" class="visually-hidden" id="live-alert"></div>
<!-- 見た目のアラート面。読み上げは上の枠が担うので aria-hidden にする -->
<div class="banner" id="banner" hidden aria-hidden="true">
<p id="banner-text"></p>
</div>
<style>
.visually-hidden { position: absolute; inline-size: 1px; block-size: 1px;
overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.banner { padding: var(--space-3) var(--space-5);
border: 1px solid var(--color-border);
border-inline-start: 4px solid var(--color-accent); }
.banner p { margin: 0; }
.banner.is-error { border-inline-start-color: var(--color-danger);
color: var(--color-danger); }
</style>
<script>
var statusRegion = document.getElementById("live-status");
var alertRegion = document.getElementById("live-alert");
var banner = document.getElementById("banner");
function notify(message, isError) {
statusRegion.textContent = "";
alertRegion.textContent = "";
(isError ? alertRegion : statusRegion).textContent = message; // 枠は残し、中身だけ差し替える
banner.hidden = false;
banner.classList.toggle("is-error", !!isError);
document.getElementById("banner-text").textContent = message;
}
notify("保存しました"); // polite。今の読み上げの後に
// 続けて呼ぶと、polite が読まれる前に notify() の1行目が器を空にしてしまう。
// 2件を聞き比べるなら、前の1件が読み終わるだけの間を置く
setTimeout(function () {
notify("保存に失敗しました。もう一度お試しください。", true); // assertive。割り込んで読む
}, 3000);
</script>
この道具は JavaScript で動きます。無効の場合は、出典の MDN「ARIA ライブリージョン」を確かめてください。