ウェブアプリのアクセシビリティガイド
Vegaウェブアプリでは、WCAG(最小AA、英語のみ)とWAI-ARIA(英語のみ)のガイドラインに従うことをお勧めします。WCAGは、アクセシビリティのあらゆる側面をカバーしています。
アクセシビリティの目標は、次のような種類の障がいのあるユーザーを支援するTVアプリを提供することです。
- 視覚 - 色覚異常から全盲まで
- 身体 - 細かい動きの制限から身ぶりが困難な状況まで
- 音声 - 発音障害から言葉を話せない状況まで(音声入力が使用される場合)
- 認知 - 学習障害、複雑な指示の理解が困難など
- 聴覚 - 部分的な難聴から全失聴まで
WebViewには、HTMLアプリ、ReactJSアプリ、Angularアプリのいずれかを使用できます。アクセシビリティ対応のWebViewには次の3つのレイヤーがあります。
- ウェブアプリ: 開発者は、アクセシビリティに対応するコードを記述して実装する必要があります。
- Vega WebViewラッパー: Vegaチームによって提供されます。
- OS: 必要なすべてのアクセシビリティサポートとAPIはOSレベルで提供されます。
Vega WebViewラッパー
HTML/Angular/ReactアプリをVegaウェブアプリにするには、Vega WebViewラッパーでラップします。
フォーカスがアプリ内に渡されるようにする必要があります。そのためには、次の要件に従うことが重要です。
- 初期フォーカスをアプリコンテナーに設定する必要があります。
- TVリモコンイベント(D-Pad、選択)をキーボードイベントとして公開します。
- デバイス上でユーザー補助機能を使用してアプリをテストします。
ウェブアプリ
アプリをアクセシビリティ対応にする作業の対象となるのはこのレイヤーです。VueJS、ReactJS、React Native(英語のみ)、Vega向けReact Native、AngularJS(英語のみ)などのフレームワークで、JSXまたはHTMLに似たテンプレートを使用してコードを記述します。
次のリソースを参照してください。
アクセシビリティガイドライン
アクセシビリティを実装するには、以下のガイドラインを使用してください。
セマンティックHTML構造
- 意味のあるHTMLタグを使用します。たとえば、
<header>、<footer>、<nav>などのセマンティックHTMLタグを使用します。ボタンには、<div>や<span>ではなく<button>要素を使用します。リンクには、非セマンティック要素ではなく<a>を使用します。これらのセマンティックタグは、プラットフォームおよびVoiceView、拡大鏡、TextBannerなどのユーザー補助機能によって認識されます。ほとんどのアクセシビリティ機能は、正しく使用すれば自動的に処理されます。 - 階層的な見出し構造を使用します。
<h1>から<h6>まで、アプリ内で見出しの順位を適切に維持します。これにより、スクリーンリーダーやその他のユーザー補助機能がコンテンツ階層を理解でき、全体的なナビゲーションが向上します。
Accessible Rich Internet Application(ARIA)タグ
- 状況によっては、非セマンティック要素を使用することが必要になる場合があります。たとえば、タイル、カード、カルーセルのようなカスタムコンポーネントを作成する場合です。このような場合は、要素の目的と動作をユーザー補助機能に伝えるために、ARIA属性を使用します。
- 簡単に言うと、ARIA属性によって次の3種類の情報を提供できます。
- その要素は何か(例:role="button")
- それは何をするか(例:aria-pressed、aria-expanded)
- 追加のコンテキストやラベル(例:aria-label、aria-describedby)
- 使用できるARIAタグ、プロパティ、メソッドの一覧については、ARIA Authoring Practices Guide(英語のみ)を参照してください。
- 以下はARIAの使用例です。
<section aria-labelledby="features-title">
<h2 id="features-title">アクセシビリティ機能</h2>
<p>このセクションでは、コンテンツをアクセシビリティ対応にする方法について説明します。</p>
</section>
代替テキストまたは画像とアイコンの説明
VoiceViewでは画像やグラフィックは認識されません。そのため、代替テキストまたは意味のある説明を提供します。たとえば、設定アイコンには「設定」のような説明を使用し、「設定アイコンの画像」や「アイコン」という説明は避けます。 VoiceViewは、「画像…」や「リンク画像…」という言葉を追加します。したがって、「画像」や「アイコン」などのテキストを追加しても意味はありません。
<img src="" alt="設定">
- 装飾画像: ユーザーにとって価値のない純粋に装飾目的の画像については、altタグを省略します。
- 繰り返されるテキスト: 近くにあるテキストと同じ内容が画像に含まれている場合は、altタグやaria-labelでテキストを繰り返さないでください。
フォーカス管理
- 要素に対するフォーカスを明確に表示する必要があります。WACGのガイドラインに従ってください。
- セマンティックHTMLタグ(button、a)を使用している場合は、デフォルトでフォーカスリングが表示され、アプリのデザインに合わせたカスタマイズも可能です。VoiceViewは、これらのタグを識別して読み上げることができます。
- 初期フォーカスには、React/Angularの
autoFocusプロパティを使用します。 - 非セマンティックタグを使用している場合は、フォーカスを適用するカスタムJavaScriptコードと、onFocusのカスタムスタイルを記述します。
- 次の場合にのみ
tabindexを使用します。- フォーカス可能でない要素をフォーカス可能にしている場合。
- フォーカス順序を細かくカスタマイズする場合。これはモーダルやカスタムコンポーネント向けです。 ```html
tabindexを使用するフォーカス可能なdiv// 要素をフォーカス可能にします。 ```
- 文字間隔: 一貫性を保ち、間隔が狭すぎたり広すぎたりしないようにします。
- すべて大文字にしない: 特に長い文章の場合に読みにくくなります。
- 行の高さ: 読みやすさを向上させるために、WCAG(英語のみ)に従って
1.5(または150%)以上を使用します。 - タイポグラフィの一貫性を保ちます。
プログラムによるアナウンス
タグのないソフトウェアを開発している場合や、プログラムで情報をアナウンスする必要がある場合のために、開発者が使用できるオプションが用意されています。これは特に、キャンバスを使用してグラフ、図、対話型ナビゲーション、3Dワールド要素を描画するウェブアプリで役立ちます。
オプション1: アナウンス専用のdivを作成し、アナウンスに使用するテキストを更新します。
<!-- index.html -->
<div id="announcer" aria-live="assertive" aria-atomic="true"></div>
<script>
const announcerDiv = document.getElementById("announcer");
// 更新をシミュレートします。
setTimeout(() => {
announcerDiv.textContent = "新しいお知らせがあります。";
}, 5000);
</script>
オプション2: postMessageを使用してVega WebViewコンテナーにメッセージを送信し、onMessageを使用してそのメッセージを処理します。onMessageで、AccessibilityInfo.announceForAccessibility();を呼び出します。これには多少の設定が必要ですが、最終的にSpeechSynthesisと同じように動作します。
SpeechSynthesisは、WebViewコンポーネントでは現在サポートされていません。postMessageとonMessageを使用すると、ある程度の実装を作成することは可能です。ただし、現時点ではAccessibilityInfoで模倣できない動作がいくつかあります。以下の例では、JSON APIやソケットデータの業界標準と同様のtype-valueメッセージパターンが使用されています。これにより、メッセージの送受信時に、さまざまなデータ型のシリアル化と逆シリアル化を簡単に行うことができます。上のスクリプトはウェブアプリで、下のスクリプトはVegaウェブアプリのコードです。
<!-- index.html -->
<script>
const message = JSON.Stringify({
type: "announcement",
value: "新しいお知らせがあります。"
});
// postMessageを使用して、Vegaウェブアプリにデータを送信します。
window.ReactNativeWebView.postMessage(message);
</script>
// App.tsx
import { AccessibilityInfo } from "@amzn/react-native-kepler";
export const App = () => {
// typeが"announcement"の場合に値を返すように実装します。
const getAnnouncement = (message: string) => {};
return (
<WebView
source={{ uri: 'https://amazon.com' }}
// onMessageを使用してpostMessageからデータを受信します。
onMessage={(event: WebViewMessageEvent) => {
const announcement = getAnnouncement(event.nativeEvent.data);
// アナウンスを実行します。
AccessibilityInfo.announceForAccessibility(announcement);
}}
</WebView>
);
};
タイポグラフィと色
- フォントサイズは、読みやすさの基準を満たしている必要があります。
- 色のコントラスト比は、通常のテキストでは4.5:1以上、大きいテキストでは3:1以上にします。WCAGのチェッカー(https://webaim.org/resources/contrastchecker/)(英語のみ)を使用できます。
- 視覚的なフォーカスは、背景に溶け込まない色にする必要があります。
- フォントファミリーには、わかりやすい書体を選択する必要があります。草書的すぎる書体や細すぎる書体は避けてください。
- コンテンツが読みやすくなるように行の高さを設定します。
ほかにも多数の考慮事項があります。
VoiceView
VoiceViewを使用してテストを行って、重複するアナウンスを防ぎ、正しい読み上げ順序を維持し、ライブ更新(aria-live)を有効にします。一般的な問題については、よくある質問(FAQ)を確認してください。
再生、Alexa、その他のオーディオの動作をテストします。
非対話型コンテンツをアクセシビリティAPIから隠蔽するには、aria-hidden="true"を使用します。詳細については、MDNのドキュメントを参照してください。これには、次のようなコンテンツが該当します。
- 純粋に装飾目的のコンテンツ(アイコンや画像など)
- 重複するコンテンツ(繰り返されるテキストなど)
- 画面外にあるコンテンツまたは折りたたまれているコンテンツ(メニューなど)
Vega WebViewのユーザー補助機能
- TVリモコン(D-Pad、戻る、選択)
- VoiceView(スクリーンリーダー)
- 拡大鏡(画面の拡大)
- キャプション/字幕

WebViewでのアクセシビリティ要素の有効化
VoiceViewの有効化
- [ユーザー補助の設定] に移動します。
- [VoiceView] をオンに切り替えます。

VoiceViewからの要素の隠蔽
VoiceViewから要素を隠蔽するには、次のコードを使用します。
aria-hidden="true"
デフォルトのアクセシブル名がない要素をVoiceViewに通知する方法
VoiceViewが要素を認識できるようにするには、次のコードを使用します。
<button aria-label="Close dialog">X</button>
動的な値のアナウンス
HTML、ReactJS、Angularではaria-liveを使用します。詳細については、ARIAのaria-live属性を参照してください。動的な値をアナウンスするには、次のコードを使用します。
<div aria-live="polite" id="status"> <!— Text inserted here will be announced --></div>
テストケース
以下は、推奨される最小限のテストケースです。これらをアプリのアクセシビリティテストとして使用できます。
VoiceView
VoiceViewを有効または無効にする
- [ユーザー補助の設定] に移動します。
- VoiceViewのオン/オフを切り替えます。
VoiceViewを有効にしてアプリを使用する
- VoiceViewを有効にします。
- リモコンを使用してアプリのナビゲーションを行います。
- 各UI要素の音声プロンプトを確認します。
新しい画面のテキストの読み上げを確認する
新しい画面では、ヘッダー、説明、使用ヒント、案内テキスト、現在フォーカスのある項目が読み上げられます。
- アプリのさまざまなセクション(ホーム、設定、コンテンツなど)に移動します。
- VoiceViewの出力を確認します。
ナビゲーションと要素の読み上げを確認する
ユーザーがすべてのアクション可能な要素に移動できること(ボタン上で方向パッド/選択/クイック選択アクションを使用)、フォーカスのある要素が完全に読み上げられること、その要素に関連する静的テキストが通常モードで読み上げられることを確認します。
フォーカスのある要素で時間を置いた後の読み上げを確認する
少し時間を置くと(0.5秒前後)、使用ヒント、案内テキスト、説明、静的テキストが読み上げられます。
画像とアイコンに説明テキストが含まれていることを確認する
画像に指示が記載されている場合は、すべての指示を代替テキストにも記述して、VoiceViewで読み上げられるようにする必要があります。
VoiceViewをレビューモードで確認する
VoiceViewを有効にした状態で、メニューを2秒間長押しします。ユーザーは、すべてのテキストとコントロールに移動して(方向パッドの左/右)、情報のレベルを変更できます(方向パッドの上/下)。レビューモードでは、アクション可能でないテキストと項目も読み上げられる必要があります。
アクセシビリティジェスチャーを確認する
たとえば、項目をダブルクリックしてアクティブ化したり、長押ししたりします。
拡大鏡(画面のズーム)
拡大鏡を有効または無効にする
- ユーザー補助機能に移動します。
- 拡大鏡を有効にします。
- 拡大/縮小できることを確認します。
UI全体でズーム機能を確認する
- テキスト、ボタン、画像を拡大してみます。
- スケーリングと表示が正しく行われることを確認します。
ズームしても読みやすさが維持され、コンテンツが表示領域に収まる
- すべての画面で拡大/縮小を行います。
- レイアウトが維持され、スクロールが機能することを確認します。
1.5倍に拡大する(初回)
- 設定に移動します。
- ズームがオフになっていることを確認します。
- ズームを有効にします。
- ズームとアプリの動作を確認します。
初回の設定以降、ユーザーの選択に従ってズームが保持される
- 設定に移動します。
- ズームがオフになっていることを確認します。
- ズームを有効にします。
- ズームとアプリの動作を確認します。
- アプリを閉じます。
- アプリをもう一度開くか、デバイスの電源を入れ直します。
- 前回のズームレベルが保存されていることを確認します。
拡大鏡がフォーカスに従うことを確認する
ユーザーがアクション可能なコントロールに移動でき(方向パッド/選択を使用)、拡大鏡がフォーカスを追従することを確認します。
ユーザーがすべてのテキストとコントロールを参照できることを確認する(メニュー+方向パッドを使用して移動)
字幕/キャプション
字幕を有効/無効にする
- ビデオを再生します。
- プレーヤー/設定で字幕を切り替えます。
- 表示を確認します。
ユーザーがクローズドキャプションのスタイルを設定できることを確認する
グローバル設定が適用されているときに、ローカルプレーヤーのCC設定を使用します。
- 字幕の設定を変更します。
- UIが適切に更新されることを確認します。
字幕の設定がセッションをまたいで保持される(該当する場合)
- 有効にします。
- アプリを終了します。
- もう一度開きます。
- 設定が保持されるかどうかを確認します。
字幕が正確で音声と同期していることを確認する
- コンテンツを再生します。
- 字幕が同期されていて正確であることを確認します。
正確なクローズドキャプションがユーザーに表示されることを確認する
キャプションは、大きな遅延なくコンテンツに追従する必要があります。
フォント/テキストサイズ
テキストサイズを拡大/縮小する
- フォント設定にアクセスします。
- サイズを調整します。
- UI全体でテキストが正しく拡大/縮小されることを確認します。
フォントの変更がアプリ全体で保持される
- フォントサイズを変更します。
- 別の画面に移動します。
- 一貫性を確認します。
大きいフォントでレイアウトが崩れない
- フォントサイズを最大に設定します。
- UIが切り詰められたり、重なったりしないことを確認します。
フォーカス/視覚的なインジケーター
アクション可能なすべての要素にフォーカスリングが表示される
- リモコンを使用してすべてのUIに移動します。
- 各要素のフォーカスリングを確認します。
フォーカス順序に一貫性がある(論理的なナビゲーション/フロー)
- リモコンを使用してナビゲーション操作を行います。
- フォーカス順序が直感的(上から下、左から右)であることを確認します。
オプション: フォーカス変更時の音声フィードバックを確認する
- オーディオキューを有効にします。
- ナビゲーション操作を行います。
- フォーカス変更時の音声通知を確認します。
モーダルを閉じた場合など、ユーザーアクションの後にフォーカスが失われない
- モーダルまたはダイアログを開いて閉じます。
- フォーカスが期待どおりの要素に戻ります。
ナビゲーション
リモコンによるナビゲーションができる
- D-Pad、戻る、選択の各ボタンを使用します。
- タッチ入力なしですべての領域にアクセスできることを確認します。
キーボードナビゲーションがサポートされる(該当する場合)
- 外部キーボードまたはアクセシビリティ対応入力デバイスでテストします。
- 対話型のすべての領域を確認します。
トラップゾーンがない(すべての領域から別の要素に移動できる)
- モーダル、メニュー、カルーセルに移動したり、そこから別の要素に移動したりします。
- どこにも移動できなくなる場所がないことを確認します。
レイテンシ
アクセシビリティメタデータが標準ペイロードパッケージの一部として読み込まれることを確認する
コンテンツを読み込み中であることが画面上(視覚と音声)でユーザーに通知されることを確認する
接続がタイムアウトしてもユーザーがブロックされないことを確認する
オフラインの場合にも当てはまります。
設計へのアクセシビリティの組み込み
画像とアイコンが説明テキストでマークアップされていることを確認する
画像に指示が記載されている場合は、すべての指示を代替テキストに記述して、VoiceViewで読み上げられるようにする必要があります。
ステータスが複数の手段で伝達されることを確認する
伝達手段には、テキスト、色、サウンドなどがあります。
すべてのアイコンに説明が指定されていることを確認する
よく使用されるアイコンにもテキストの説明が必要です。
トラブルシューティング
VoiceViewが有効になっていてもアプリ内の項目が読み上げられない
アクセシビリティマークアップを確認してください。
UI要素がボタンとして読み上げられる
これは、UI要素にアクセシビリティラベルまたは説明が設定されていない一方で、アクセシビリティロールがボタンとして設定されていることが原因です。
UI要素が視覚的な表示と一致しない
アプリで、フォーカスのある要素がアクセシビリティに対応するように正しく設定されていない可能性があります。
タイトルやUI要素が複数回読み上げられる
アクセシビリティアナウンスが重複している可能性があります。重複するアクセシビリティアナウンスをすべて削除します。
ビデオの再生中に読み上げが続行される
ラベルが不適切に使用されているために、フォーカスがコンテンツの詳細に設定されている可能性があります。フォーカスは、内部にテキストを含まないビデオプレーヤーコンポーネントにあるのが期待される動作です。アプリでは、ビデオの再生中、画面上で視覚的にフォーカスのない要素/ノードにフォーカスを設定してはなりません。
オーディオダッキングが機能しない
ビデオの再生中にVoiceViewが読み上げを開始した場合、VoiceViewの読み上げが優先され、ビデオ再生のオーディオの音量は下がる必要があります。
関連トピック
Last updated: 2025年10月7日

