テキストが逐次表示される UI ではライブリージョンに一工夫いる話

流行りの生成 AI のようにテキストが逐次表示される UI では、対象の要素に直接 aria-live を指定すると期待しない読み上げになるので注意。

例えば、最終的に生成されるメッセージが以下で、それを div.message に表示するとする。ライブリージョン自体の説明は MDN に投げる。 https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA/ARIA_Live_Regions

<div className="message" aria-live="assertive">
	 ボット: それは素晴らしいアプローチですね!(……生成結果が続く)
</div>

実際にはレスポンスはチャンクとなってストリームされてくる。

- ボット: それは
- 素晴らしい
- アプローチですね!
- (……生成結果が続く)

そうすると、要素は時間経過とともに次のように遷移する。

<div className="message" aria-live="assertive">
	 ボット: それは
</div>
↓
<div className="message" aria-live="assertive">
	 ボット: それは素晴らしい
</div>
↓
<div className="message" aria-live="assertive">
	 ボット: それは素晴らしいアプローチですね!
</div>
↓
<div className="message" aria-live="assertive">
	 ボット: それは素晴らしいアプローチですね! (……生成結果が続く)
</div>

この場合、読み上げは以下のようになる(注: 確認は NVDA のみ)。

ボットそれは、 → ボットそれは素晴らし、 → ボットそれは素晴らしいアプロ、 → ボット: それは素晴らしいアプローチですね!

ようするに、チャンクが追加されるたびに現在の読み上げを中止し、先頭に巻き戻って読み上げが始まる。挙動としてはこれが正しい。

次のようなアプローチで読み上げを改善できる。

やり方

div.messagearia-live="assertive" は削除して、読み上げ専用の要素を用意する。

<div aria-live="assertive" aria-atomic="true" className="sr-only"></div>

レスポンスの生成中は、生成中であることを伝えるメッセージを設定する。

<div aria-live="assertive" aria-atomic="true" className="sr-only">
	AIがテキストを生成中です
</div>

生成完了後に、メッセージの全文を設定する。

<div aria-live="assertive" aria-atomic="true" className="sr-only">
	ボット: それは素晴らしいアプローチですね!(……生成結果が続く)
</div>

こうすると、以下のように自然な読み上げになる。

AIがテキストを生成中です。 → (生成完了後) → 	ボット: それは素晴らしいアプローチですね!(……生成結果が続く)

ChatGPT の実装を追ってみたら、こう実装されていた、という話。おしまい。

No comments yet