通知・ダイアログ

アラート(通知)

解説あり

Alert

フォーカスを奪わずに重要メッセージを即座に読み上げる、live region を使った通知。

アラート(role="alert")とは?

アラートは、「保存しました」「エラーがあります」のような短い・重要なお知らせを、ユーザーの操作の流れを止めずに伝えるための仕組みです。 画面の隅に出るトースト通知や、フォーム送信後のメッセージなどが典型です。

ポイントは role="alert" を付けた領域をあらかじめ空のまま DOM に置いておき、 あとからJavaScriptでメッセージ文字列を差し込むこと。これだけでスクリーンリーダーが自動で読み上げてくれます。フォーカスは奪いません。

なぜアクセシビリティが大事なの?

目で画面を見られない/見えにくいユーザーを想像してください。

つまり「読み上げは割り込む/フォーカスは奪わない」が両立できるのがrole="alert" の良いところです。

ライブデモ(推奨実装)

下のボタンを押すと、ボタンの下にメッセージが表示されます。 このときフォーカスはボタンに留まったままです。

フォーカスを奪わないアラート

試してみよう:ボタンに Tab で移動 → Enter で「保存」。フォーカスはボタンのまま動かず、スクリーンリーダーだけがメッセージを読み上げます。

ポイント

スクリーンリーダー(macOSなら +F5 で VoiceOver)をオンにしてボタンを押すと、 フォーカスは動かないのに「入力内容を保存しました」と読み上げられます。 これが role="alert"(=割り込み読み上げ)の効果です。

キーボード操作

キー動作必須/任意
(専用キーなし)アラート自体に特別なキー操作はない。フォーカスを移さないのが正しい挙動。必須
Tabメッセージを表示させるトリガー(ボタンなど)へは通常どおり移動できる。必須

補足

アラートは「受け身の通知」です。閉じるボタンを付けるなら、それは普通の<button> としてキーボードで操作できるようにします(アラート領域自体にフォーカスは当てません)。

必要な WAI-ARIA / ロール

付ける場所属性 / ロール意味
通知領域のコンテナrole="alert"緊急の読み上げ領域にする。aria-live="assertive" 相当の挙動になる。
通知領域のコンテナaria-atomic="true"(任意)内容が変わったとき、領域全体をまとめて読み上げる。
コンテナの設置タイミング(属性ではなく実装)最初から空で DOM に置いておく。あとから文字を差し込むと読み上げられる。後から領域ごと挿入すると読まれないことがある。

実装:推奨パターン(Good)

良い例 / 推奨

空の role="alert" 領域を先に置き、あとからテキストだけを差し込みます。フォーカスは動かしません。

マークアップ:

<!-- ① 空の通知領域を最初から DOM に置いておく -->
<div id="status" role="alert"></div>

<button type="button" id="save">保存する</button>

メッセージの差し込み:

const region = document.getElementById('status');
const button = document.getElementById('save');

button.addEventListener('click', () => {
  // ② 後からテキストを差し込むと、role="alert" 領域は
  //    自動で読み上げられる。フォーカスは button のまま動かさない。
  region.textContent = '入力内容を保存しました。';
});

補足

同じ文言を続けて入れると読み上げが繰り返されないことがあります。 回数表示を加える・一度空にしてから入れ直す、などで「内容が変わった」と認識させられます。 緊急でない通知(例:「自動保存しました」)は role="status"(=aria-live="polite")を使い、割り込まず読み上げるのが親切です。

アンチパターン(Bad)

下は rolearia-live も無い、ただの「見た目だけのバナー」です。目で見える人には伝わりますが、スクリーンリーダー利用者には何も伝わりません。

読み上げられないバナー(role なし)

試してみよう:見た目はメッセージが出ますが、スクリーンリーダーでは無言のままです。重要なお知らせが完全に無視されてしまいます。

<!-- ❌ 見た目だけのバナー(role も aria-live も無い) -->
<button type="button" onclick="showBanner()">保存する</button>

<div id="banner" class="banner" style="display:none">
  入力内容を保存しました。
</div>
<!-- 画面には出るが、スクリーンリーダーには何も伝わらない -->

悪い例 / 避ける

この実装の問題点:

  • 読み上げられないrole="alert"aria-live も無いので、変化が通知されない。
  • 気づけない — 画面の別の場所を読んでいるスクリーンリーダー利用者には存在自体が分からない。
  • 逆に「読み上げさせたいから」とフォーカスを奪うのも誤り。操作位置を見失わせる。

ポイント

正解は「フォーカスは動かさず、role="alert" でテキストだけ差し込む」。 読み上げと操作位置の両方を尊重できます。

実装チェックリスト


原文(英語):Alert Pattern — W3C APG(新しいタブで開きます)