この記事でわかること

  • 状態の知らせについて定めた、WCAGの達成基準4.1.3の内容
  • 「状態の知らせ」に当たるものと、当たらないもの
  • 知らせの入れ物にrole="status"を付ける書き方
  • roleを付けない入れ物と、ブラウザで比べた結果

保存のボタンを押すと、画面の隅に「保存しました」と出る。検索すると、一覧の上に「5件見つかりました」と出る。目で見ている人にはすぐ分かるこうした知らせ(ステータスメッセージ)も、画面を読み上げて使う人には、そこへ移って読まない限り届きません。この記事では、フォーカスを動かさずに出る知らせを読み上げに乗せる作り方を、WCAG 2.2の達成基準4.1.3を軸に整理します。

元にしたのは、W3Cの達成基準4.1.3の解説(Understanding)と、技法ARIA22・ARIA23・ARIA19、失敗例F103で、2026年11月1日に原文を確かめました。例の検索の画面と商品の名前は、この記事のために作ったものです。特定のツールやスクールの紹介はしません。

先に結論: 知らせの入れ物にroleを付け、最初から置いておく

知らせを書き込む入れ物にrole="status"を付け、ページを開いた時点から置いておきます。 知らせが出たら、その入れ物の中に文を書きます。知らせの中身によって、使う技法が分かれます。

知らせの中身 例 使う技法
操作の結果・画面の状態 「保存しました」「5件見つかりました」 role="status"(ARIA22)
入力の誤り・注意 「郵便番号の形が違います」 role="alert"など(ARIA19)
処理の進み具合・順に増える記録 チャットの発言・作業の記録 role="log"(ARIA23)

状態の知らせに関わる基準(4.1.3)

WCAG 2.2の達成基準4.1.3(レベルAA)は、マークアップで作ったページの状態の知らせを、roleや属性で見分けられるようにし、フォーカスを受け取らなくても支援技術が利用者に伝えられるようにすることを求めています。

解説では、この基準で助かるのは、スクリーンリーダーを使う、目の見えない人や見えにくい人だとしています。目で見ている人の多くは、画面の端に足された文にも気づけますが、読み上げで使う人は、知らせが自動で読まれなければ気づけません。

「状態の知らせ」に当たるものと、当たらないもの

WCAGの定義では、状態の知らせは、状況の変化を伴わない内容の変化のうち、次のどれかを伝えるものです。

  • 操作が成功したことや、操作の結果
  • アプリが待ちの状態にあること
  • 処理の進み具合
  • エラーがあること

解説の例には、カートに入れた後の「5点」、送信の後の「送信しました」、写真をアルバムに入れた後の「保存しました」が並んでいます。

一方で、検索で得た結果の一覧そのものは、状態の知らせに当たらないとしています。当たるのは「検索しています」「18件見つかりました」のような短い文です。エラーをダイアログで出す場合も、ダイアログがフォーカスを受け取るので、この基準の対象から外れます。

書き方の例: 検索の件数をrole="status"で知らせる

次のHTMLは、検索の欄と、件数を知らせる入れ物、結果の一覧を置いたページの例です。件数の入れ物は、最初は空のままにしておき、検索のたびに中の文を書きかえます。

<form id="search" role="search">
  <label for="q">商品の名前で探す</label>
  <input id="q" name="q" type="search">
  <button type="submit">検索</button>
</form>

<!-- 知らせの入れ物は、最初から空のまま置いておく -->
<p id="search-status" role="status" aria-atomic="true"></p>
<ul id="results"></ul>

<script>
  const items = ["ノートPCスタンド", "USBハブ", "ノートPCケース"];
  document.getElementById("search").addEventListener("submit", (event) => {
    event.preventDefault();
    const word = document.getElementById("q").value.trim();
    const hits = items.filter((name) => name.includes(word));
    document.getElementById("results").replaceChildren(...hits.map((name) => {
      const li = document.createElement("li");
      li.textContent = name;
      return li;
    }));
    // 一覧そのものではなく、件数の短い文を入れ物の中に書く
    document.getElementById("search-status").textContent = hits.length + "件見つかりました";
  });
</script>

技法ARIA22では、statusのroleには、暗黙にaria-liveのpoliteの値があり、知らせが足されると支援技術が利用者に伝えられるとしています。statusは初期の設定で入れ物の中身をまとめて読ませますが、そう扱わない環境もあるため、全体を読ませたいときはaria-atomic="true"を明示するよう勧めています。

手順: 自分のサイトの知らせを見直す

  1. 画面に出る知らせを書き出す: 保存・送信・検索・カートへの追加など、操作の後に出る短い文を並べます
  2. フォーカスが動くかを見る: ダイアログのようにフォーカスを受け取るものは、この基準の対象から外します
  3. 入れ物のroleを見る: 残った知らせの入れ物に、role="status"などのroleかaria-liveが付いているかを確かめます
  4. 入れ物が先にあるかを見る: 知らせが出る前から、roleを付けた入れ物がページに置かれているかを確かめます
  5. 知らせが入れ物の中に出るかを見る: 文が入れ物の外に書かれていないか、画像の知らせには代わりの文があるかを確かめます

試した結果

上のHTMLと、件数の入れ物からroleとaria-atomicを外した版、aria-atomicだけを外した版を作りました。どれも自分のPCの中で配信し、画面を出さないChromeで読み込み、ブラウザが支援技術に渡すアクセシビリティの情報を読み取って比べました。

  • 上のHTMLでは、件数の入れ物の役割はstatusで、読み上げの設定(live)はpolite、まとめて読ませる設定(atomic)はtrueでした
  • 検索の欄に「ノートPC」と打ってEnterを押すと、入れ物の文は「2件見つかりました」になり、一覧は2行でした。フォーカスは検索の欄に残ったままでした
  • 「タブレット」で検索すると、入れ物の文は「0件見つかりました」になり、一覧は空になりました
  • roleを外した版でも、画面の文は同じように「2件見つかりました」に変わりました。ただ、入れ物の役割はただの段落で、liveの設定はありませんでした
  • aria-atomicだけを外した版でも、試したChromeでは、atomicはtrueのままでした

使ったブラウザは、作業用のMacに入れたGoogle Chrome 156(画面を出さない形)です。スクリーンリーダーで実際に読み上げさせることはしていません。

自分で直すか、相談するかの判断

目安は、「知らせの入れ物を、ページを開いた時点で置けるか」です。入れ物にroleを付ける、知らせの文をその中に書く、といった直しは、HTMLとスクリプトの小さな変更で済みます。

知らせを出す仕組みが部品やライブラリの中にあって手を入れにくい場合や、知らせが多くて読み上げがうるさくなりそうな場合は、作った人と相談して決めます。解説でも、知らせが多すぎないか、利用者に試してもらうよう勧めています。作りに迷うときは、Webデザインの講座で講師に見てもらう方法もあります。

つまずきやすいところ

まとめ

  • 「保存しました」や検索の件数のように、フォーカスを動かさずに出る知らせは、読み上げにも乗るようにします
  • 知らせの入れ物にrole="status"を付け、ページを開いた時点から置いておきます
  • 全体を読ませたいときは、aria-atomic="true"も付けます
  • 入力の誤りはrole="alert"、順に増える記録はrole="log"の技法を使います