トピックを検索
読んでいる最中に自動更新で書き換わってしまう新着一覧
ニュースサイトの新着一覧は60秒ごとに内容を取得し直して丸ごと書き換えるうえ、止める手段もないため、読んでいた記事がフォーカスごと消えてしまう
list.innerHTML = await response.text(); 問題
スクリーンリーダー、キーボード、画面拡大ソフトで一覧を読む人は、1分ごとに読んでいた記事を見失い、しかも更新を止める手段がない
地域のニュースサイト「Harbour Herald」には新着ページがあります。その日の記事を新しい順に並べた番号付きの一覧で、記事ごとに掲載時刻が付いています。古いニュースを表示し続けないよう、スクリプトが60秒ごとに一覧を取得し直し、ページ上の一覧に上書きします。一覧全体を眺める人にとっては、新しい記事が上に現れるだけです。
スクリーンリーダーの利用者が見出しをTabキーで順にたどり、3件目の「図書館、週末の開館時間を延長」で止まって、開くかどうか考えています。ページを読み込んでから1分たつと、一覧が上書きされます。利用者がいたリンクはページから取り除かれ、同じ内容の新しいリンクに置き換わるため、フォーカスはページそのものに戻り、何が起きたのかを伝えるものもありません。リンクが毎回新しい要素になるので、新しい記事が来ていなくても、同じことが1分ごとに起こります。10時43分にフェリーの記事が入ると、図書館の記事は1つ下にずれます。画面拡大ソフトでこの記事を拡大していた人の目の前で、記事は視界から外れ、代わりに橋の記事がその場所に来ます。ページには、更新を止める手段がありません。
達成基準3.2.5「要求による変化」(レベルAAA)は、コンテキストの変化が利用者の求めたときにだけ起こるか、利用者がそうした変化を止められることを求めています。WCAGは、ページ全体を一度に見られない人を混乱させかねない大きな変化をコンテキストの変化と呼び、フォーカスを別の場所へ移すことや、ページの内容を大きく並べ替えることもそこに含めています。一覧の上書きは、その両方を起こします。主要な内容が勝手に置き換わり、フォーカスのあるリンクも一緒に消えます。フォーカスを持つ要素が取り除かれると、ブラウザーはフォーカスをページそのものへ移し、document.activeElement はbodyを返します。W3Cはこれを失敗例F61として挙げています。メインのビューポートの内容が自動更新で変わり、利用者が止められないというもので、最初の例は、最新の見出しを出すために自動で更新し続けるニュースサイトです。自動更新に対する十分な達成方法G76は、自動で更新する代わりに、更新を利用者が求められるようにするものです。
ブラウザーの側に、この書き換えを止める理由はありません。タイマーは誰かが読んでいるかどうかに関係なく動き、innerHTML は、新しいマークアップが同じでも、置き換える要素をフォーカスのあるものも含めてすべて捨てます。
この一覧は、ページのほかの部分と並んで自動で更新されるため、レベルAの2.2.2「一時停止、停止、非表示」の対象にもなります。2.2.2は、こうした更新を一時停止、停止、非表示にするか、更新の頻度を変える手段を求めています。下の二つの修正は、この2.2.2も満たします。一部を書き換えるのではなく、タイマーでページ全体を再読み込みするページは、まず2.2.1に適合しません。こちらは時間がたつと自動で再読み込みや転送をするページで扱います。
この更新は、一覧全体を見て新しいものを拾う人のためのものです。一覧を1件ずつ読み進めるすべての人にとっては負担になり、ゆっくり読む人ほど何度も巻き込まれます。
10グループ中4グループに影響
- 全盲 (影響あり)
- 弱視 (影響あり)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響あり)
- 筋力・可動域 (影響なし)
- 認知 (影響あり)
- 光過敏 (影響なし)
- 視覚を使わない 見出しを順に読んでいるスクリーンリーダーの利用者がいるリンクは、更新のたびにページから取り除かれます。フォーカスはページそのものに戻り、どこから読み続けるかは、利用者ではなくスクリーンリーダーが決めることになります。
- 手の操作が限られる 記事までTabキーで進んできたキーボードやスイッチの利用者は、1分ごとにその記事を見失い、たどり直す途中で一覧がまた変わっていることもあります。
- 視覚が限られる 画面拡大ソフトでは一度に1、2件の記事しか見えないため、一覧が1つ下にずれると、読んでいた記事は視界から外れ、別の記事に置き換わります。画面には理由を示すものが何もありません。
- 言語・認知・学習の能力が限られる ゆっくり読む人や、記事を開いてから一覧に戻る人は、そのたびに違う並びを目にし、どこまで読んだかを追えなくなります。
マークアップに誤りはなく、スキャンはページを読み込んで数秒で離れるため、最初の更新よりずっと前に終わります。この診断では、利用者の操作なしに始まるタイマーを見張り、内容を取得してマークアップとしてページに書き込むものを ew:auto-refresh-manual-check として確認に回します。そのタイマーが主要な内容を置き換えるのか、その前に更新を止めるスイッチがあるのかは、人が見て確かめるしかないためです。ページを再読み込みするmeta refreshは、遅延が20時間未満ならaxeの meta-refresh が報告します。それより長いものは2.2.1を満たすため、この診断では axe:meta-refresh-no-exceptions として確認に回します。AIのコーディングツールに「一覧を最新に保って」と頼むと、修正前の例の setInterval を書くことがあります。
試してみる
一覧の3件目の記事までTabキーで移り、次の更新が来るのを待ってみましょう
一覧は実際の時間で60秒ごとに更新されます。待たずに試すには、デモ用の時計の「次の更新まで進める」を押してください。フォーカスがどこへ行き、読んでいた記事がどこへ移るかを見たら、それぞれの修正を適用してもう一度試してください。
問題あり 修正できますか?
修正方法
一覧は、利用者が求めたときだけ変える
<section aria-labelledby="latest-title"> <h2 id="latest-title">Latest</h2> <ol id="stories"> <li> <time datetime="10:40">10:40</time> <a href="/news/storm-warning">Storm warning for the coast tonight</a> </li> … </ol></section>問題点4点
- 誰かが読んでいるかどうかに関係なく、60秒ごとに一覧全体が置き換わります。
- フォーカスのある記事のリンクも一緒に取り除かれ、フォーカスはページに戻ります。
- 新しい記事が来ると、その下の記事はすべて1つ下にずれます。
- 更新を止める手段がありません。
新しい記事を表示するボタン
<section aria-labelledby="latest-title"> <h2 id="latest-title">Latest</h2> <button type="button" id="show-new" hidden>Show 1 new story</button> <ol id="stories"> <li> <time datetime="10:40">10:40</time> <a href="/news/storm-warning">Storm warning for the coast tonight</a> </li> … </ol></section>修正の手順4ステップ
- 60秒ごとの取得は続けますが、ページの先頭の記事より新しいものだけを求め、一覧には書き込まずに取っておきます。
- その件数を一覧の前のボタンに書き、ボタンを表示します。一覧は変わらないので、誰も読んでいる位置を失いません。
- ボタンが押されたら、新しい記事を一覧の先頭に加えます。これが、利用者の求めた変化です。
- 押したボタンはまた隠れるため、フォーカスを最初の新しい記事へ移します。利用者は、自分で表示させた記事から読み始められます。
これで修正前の例は直り、3.2.5を満たします。主要な内容は、誰かがボタンを押したときにだけ変わります。一覧が勝手に変わることはもうないので、2.2.2も満たします。
この方法を選ぶ理由:ページは、利用者が求めたときだけ変える
どちらも3.2.5を満たします。おすすめはボタンです。誰かが求めるまで何も変わらないので、先に設定を探す必要がありません。チェックボックスでは、まだ見つけていない人全員に更新が届き続けるため、単独では足りません。ニュースが入りしだい読みたい人には、ボタンだと1回の操作が増えます。チェックボックスが向いているのは、試合の速報のように、読者の多くが自動で最新になってほしいと考えるページです。その場合も、チェックボックスを先に置き、選択を覚えておくことが条件です。
フォーカスの移動先。 押されたボタンは隠れ、隠れた要素はフォーカスを保てないため、スクリプトでフォーカスを最初の新しい記事へ移します。ブラウザー任せにして、フォーカスをページへ落とさないでください。デザイン上ボタンを表示したままにするなら、件数を「新着はありません」に変えて、フォーカスをボタンに残してもかまいません。
新しい記事があることを伝える。 ボタンは何も読み上げずに現れますが、3.2.5にはそれで十分です。利用者は一覧の先頭に戻ったときに見つけます。スクリーンリーダーの利用者にも知らせたいなら、件数が0から1になったときに role="status" の領域へ短いメッセージを書きます。確認のたびに書くと、1分ごとのメッセージが次の割り込みになります。理由はスクリーンリーダーが読み上げ続けるカウントダウンタイマーで説明しています。
画面に固定した「新着」ボタン。 このボタンを、画面の上端に固定したピル型で表示するサイトもあります。マークアップでは一覧の前に置いて、読み上げとTabの順で記事より先に来るようにし、フォーカスのある記事を決して覆わないようにします。フォーカス中のリンクを隠す固定ヘッダーとバナーを参照してください。
一覧にいる間だけ止めるのは、修正になりません。 フォーカスやポインターが一覧の中にある間は更新を止めるスクリプトも、利用者が離れた瞬間に一覧を変えます。また、スクリーンリーダーが一覧を読み進めても、フォーカスが一緒に動くとは限らないため、スクリプトには誰かが読んでいることが分かりません。
新しい記事だけを先頭に加える。 一覧を書き換えずに insertAdjacentHTML('afterbegin', …) で新しい項目を加えれば、フォーカスのあるリンクはページに残り、修正前よりはよくなります。それでも、拡大して読んでいる人の前で記事がすべて下にずれるため、ボタンかチェックボックスも用意してください。
自動で再読み込みするページ。 <meta http-equiv="refresh" content="300"> を持つ新着ページは、経路が違うだけで同じ失敗であり、2.2.1にも適合しません。遅延の長さにかかわらずmeta refreshを消し、新しい記事を求めたときに読み込めるボタンやリンクを用意します。
更新そのものが目的のライブページ。 ライブブログ、試合のページ、発車案内は最新の状態を保つためにありますが、3.2.5はこれらを例外にしていません。同じボタンかチェックボックスを付けてください。試合を細かく追っている人は、ボタンを押すか、更新をオンのままにします。
デザインの案
新着一覧は、最新を追いながらも、求められるまで待てる
新しい記事が届いたことを伝える方法をさらに3通りと、一覧を勝手に変えてしまう流行りの形を2通り示します。それぞれの記事にTabキーで移動して数秒待ち、サンプルにあるものを押してみてください。
デザインファイルで
- 一覧を2通り描く:新着が届いた状態(変わるのは一覧の上のコントロールだけ)と、押した後の状態(新しい記事が先頭に並ぶ)。
- ボタンやスイッチは一覧の上に置き、ページを読んだりTabキーで移動したりしたときに、記事より先に来るようにする。
- ボタンには「新着2件」のように件数を言葉で書き、点や数字だけにしない。
- ボタンを押した後にフォーカスが移る先として、最初の新しい記事に印を付ける。
- 自動更新を用意するなら、ページを開いたときのスイッチはオフで描く。
合格
- 見出しの横の件数チップ 見出しと同じ行に置いた小さな淡いチップ「新着2件」です。#e8eef6に紺の#1f3a5fで9.84:1。一覧の場所を取らないので、現れても下の記事は動きません。押すと記事が加わり、最初の記事にフォーカスが移ります。
基本原則:ページは、利用者が求めたときだけ変える
- 更新時刻と「更新」ボタン #5f5f5f(6.39:1)の控えめな「10:40更新」の行と、その後ろの「更新」ボタンです。新しくし続ける件数はなく、時刻で一覧の新しさが分かります。一覧が変わるのは「更新」を押したときだけで、フォーカスはボタンに残ります。
基本原則:ページは、利用者が求めたときだけ変える
- オンにするまでオフの「自動更新」スイッチ 一覧の上に置いた「自動更新」のピル型スイッチで、ページを開いたときはオフです。オフは灰色#6b6b6bのトラック(5.33:1)、オンでは紺に赤い点が付きます。最新を追いたい人はオンにし、それ以外の人が頼んでいない更新に出会うことはありません。
不合格
- 先頭に滑り込んでくる記事WCAG 3.2.5 記事にTabキーで移動して待つと、その上に新しい記事が滑り込み、元の記事を押し下げます。生き生きと見えますが、読んでいた記事が頼んでもいないのに動き、画面拡大鏡では視界から外れます。サンプルでは1回だけですが、このパターンは1分ごとに繰り返します。
基本原則:ページは、利用者が求めたときだけ変える
新着
5秒後に更新自動更新までのカウントダウンの輪WCAG 3.2.5 細い輪が「5秒後に更新」とカウントダウンし、一覧全体が描き直されて、フォーカスのあった記事は消えます。輪は変化が来ることを知らせますが、止める手段はありません。サンプルのカウントダウンは1回だけですが、このパターンは更新のたびに始まり直します。
修正の確認
5項目、マウス不要
確認方法: キーボード、スクリーンリーダー、拡大表示
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。一覧のコンポーネントや更新のスクリプトを変更した際は、再度確認します。
制限
これは出発点となる実装例であり、すべてのアプリケーションでの適合を保証するものではありません。このガイドが扱うのは、タイマーで丸ごと書き換わる一覧です。ページを開いたときや文字を入力したときに開くウィンドウなど、3.2.5が利用者の操作で起こすよう求めるほかの変化も、失敗の形は同じで、直し方も同じです。利用者が求めたときに起こすことです。フォーカスや値の変更でページを変える欄やセレクトは操作するだけでページが変わるドロップダウンと入力欄で、新しいタブで開くリンクは新しいタブで開くことを伝えないリンクで扱います。読んでいた要素が取り除かれたときの動きはスクリーンリーダーによって違うため、利用者が使っているもので確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
EaseWebのサービス
修正した問題を、次のリリースで再発させない
このガイドのような修正方法を、コーディングエージェントが従うルールと、CIのチェックに組み込みます。あわせて定期的に、キーボードとスクリーンリーダーで手動の再テストを行います。