web.devの「Learn Accessibility」を読む
web.devの「Learn Accessibility」における個人的なメモ。
デジタルアクセシビリティとはなにか、なぜ重要なのか
- デジタルアクセシビリティとは、デジタル製品を設計および構築して、人の障害に関係なく、有意義かつ同等の方法で製品を操作できるようにすること
- アクセシビリティのベストプラクティスを製品のライフサイクル全体(設計、デザイン、コーディング、その他の工程)に含めて考える必要がある
個人への影響
- WHOによると世界人口の15%以上 (13億人) が障害を持っていると自己認識
- 視覚障害、運動障害、聴覚障害、認知障害、発作、前庭障害、言語障害など
Additional beneficiaries of accessibility
アクセシビリティの恩恵を受けるのは上記の障害者だけでない。
- 一時的な怪我、デバイスの問題、言語の問題、加齢による衰えなど
- 例として人だけではなく、Search engine optimization (SEO) bots. も含まれている
ビジネスへの影響
- アクセシビリティを考慮しない企業は、潜在的な収益を失う可能性がある
- 障害のある人によって、または障害のある人のために開発された技術から進化した日用品も多くある
法的な影響
- 米国では、デジタルアクセシビリティに焦点を当てた訴訟の提起が多くある
- なかでもEコマースに関連するものが多い
デジタルアクセシビリティをどのように測定するか
アクセシビリティテスト
- 国や法律、業界や製品によって満たすべき基準は異なる
- 特定の基準がなければ Web Content Accessibility Guidelines (WCAG) が推奨される
Web Content Accessibility Guidelines (WCAG)
- W3Cを通じて開発されている国際的なアクセシビリティ基準であり、デジタルアクセシビリティのための単一の共有基準を提供することが目標
- 対象はウェブベースおよびネイティブモバイルアプリにおけるデザイナーや開発者
- 上記だけでなく、ソフトウェア開発者、コンテンツクリエイター、マネージャーなどもWCAGにを理解することで、利益を享受できる
アクセシビリティの原則
POURの原則
Perceivable, Operable, Understandable, and Robust (POUR)
- 知覚可能(Perceivable)
- 非装飾的な画像と重要なアイコンに代替テキストがあるか
- ビデオにキャプション、トランスクリプト、オーディオの説明がある
- 操作可能(Operable)
- アクティブな要素にキーボードやタッチスクリーンのサポートがある
- スライドショーやビデオにコントロールがある
- 理解可能(Understandable)
- 簡潔に書かれている
- ナビゲーションが予測可能である
- エラーメッセージが明確で解決できる
- 堅牢(Robust)
- デバイスとユーザーエージェントが進化してもアクセスできる
- さまざまなインターフェイスや支援技術でアクセスできる
- デバイスのサイズや向きに関係なくコンテンツにアクセスできる
ARIAとHTML
ARIA
- Web Accessibility Initiative (WAI) によって最初に開発
- アクセシビリティを高めるためにHTML要素に追加できる属性
アクセシビリティツリー(AT)
アクセシビリティツリーはDOMツリーに基づいている。
DOM + ARIA = accessibility tree
ARIA自体は、要素の機能や外観を変更しない。
- AT利用者のみに情報が伝わる
- 開発者が適切なスタイルとコードの変更を行い、責任を持つ必要がある
ARIAの3つの主な機能
- ロール(Role)
- プロパティ(Properties)
- 状態/値(States/Values)
ロール(Role)
要素が何をするかを定義。
<div role="button">Self-destruct</div>
プロパティ(Properties)
オブジェクトの性質や関係性を定義。
<div role="button" aria-describedby="more-info">Self-destruct</div>
<div id="more-info">This page will self-destruct in 10 seconds.</div>
状態/値(States/Values)
要素に関連づけられた現在の状態や値を定義。
<div role="button" aria-describedby="more-info" aria-pressed="false">
Self-destruct
</div>
<div id="more-info">
This page will self-destruct in 10 seconds.
</div>
Full accessibility tree in Chrome DevTools
いつARIAを使うか
ARIAを使う際の5つのルール
1.ARIAを使用しない
ネイティブの要素で表現できる場合は、ネイティブの要素を使用する。
不適切な例
<a role="button">Submit</a>
適切な例
<button>Submit</button>
2.ネイティブのセマンティクスを変更しない
必要な場合を除き、ネイティブのセマンティクスを変更しない。
不適切な例
<h2 role="tab">Heading tab</h2>
適切な例
<div role="tab"><h2>Heading tab</h2></div>
3.キーボード ナビゲーションをサポートする
インタラクティブな ARIA コントロールは、キーボードでアクセスできる必要がある。フォーカスが必要な要素にはtabindex="0"を追加できる。キーボードフォーカス順序の問題を防ぐために、可能な限り正の整数を含むタブ インデックスを使用しない。
不適切な例
<span role="button" tabindex="1">Submit</span>
適切な例
<span role="button" tabindex="0">Submit</span>
4.フォーカス可能な要素を非表示にしない
tabindex="0"をもつ要素を含め、フォーカス可能な要素にrole= "presentation"やaria-hidden= "true"を付与しない。
不適切な例
<div aria-hidden="true"><button>Submit</button></div>
適切な例
<div><button>Submit</button></div>
5.インタラクティブな要素にアクセシブルな名前を使用する
インタラクティブな要素の目的は、ユーザーが操作方法を理解する前に伝える必要がある。
適切な例
<!-- A plain link with text between the link tags. -->
<a href="shoes.html">Red leather boots</a>
<!-- A linked image, where the image has alt text. -->
<a href="shoes.html"><img src="shoes.png" alt="Red leather boots"></a>
<!-- A checkbox input with a label. -->
<input type="checkbox" id="shoes">
<label for="shoes">Red leather boots</label>
ARIAとHTML
- デフォルトのHTML ロールを上書きしない
- 冗長性を減らす
- 意図しない副作用に注意する
ARIAの複雑さ
- ARIA は複雑なので、注意が必要
- 使い方を誤ると、害になるか、単純に煩わしいものになる可能性がある
- デジタルアクセシビリティは全か無かの状況ではない
- 重要なのは、学び、テストし、努力を続けること
コンテンツ構造
セマンティックなHTML要素を使用すると、要素の意味がアクセシビリティツリーに反映され、ATが解釈することで、非セマンティック要素よりもコンテンツにより多くの意味が与えられる。
ランドマーク
ARIAランドマークロール 、もしくはHTMLランドマーク要素を使用して、構造的なコンテキストを追加できる。
| HTMLランドマーク要素 | ARIA ランドマークの役割 |
|---|---|
<header> |
バナー |
<aside> |
補完的 |
<footer> |
コンテンツ情報 |
<nav> |
ナビゲーション |
<main> |
主要 |
<form> |
形状 |
<section> |
領域 |
不適切な例
<div>
<div>...</div>
</div>
<div>
<p>Stamp collecting, also known as philately, is
the study of postage stamps, stamped envelopes,
postmarks, postcards, and other materials relating
to postal delivery.</p>
</div>
<div>
<p>© 2022 - Stamps R Awesome</p>
</div>
適切な例
<header>
<nav>...</nav>
</header>
<main>
<section aria-label="Introduction to stamp collecting">
<p>Stamp collecting, also known as philately, is
the study of postage stamps, stamped envelopes,
postmarks, postcards, and other materials relating
to postal delivery.</p>
</section>
</main>
<footer>
<p>© 2022 - Stamps R Awesome</p>
</footer>
見出し
見出しレベルは全体の簡潔なアウトラインを形成する。理想的には見出しをスキップしない(ATユーザーで特に重要)。
不適切な例
<div>
<h3>Stamps</h3>
<p>Stamp collecting, also known as philately, is the study of postage stamps, stamped envelopes, postmarks, postcards, and other materials relating to postal delivery.</p>
</div>
<div>
<h3>How do I start a stamp collection?</h3>
<h2>Equipment you will need</h2>
<h4>...</h4>
<h2>How to acquire stamps</h2>
<h4>...</h4>
<h2>Organizations you can join</h2>
<h4>...</h4>
</div>
適切な例
<header>
<h1>Stamp collecting</h1>
</header>
<main>
<section aria-label="Introduction to stamp collecting">
<h2>What is stamp collecting?</h2>
<p>Stamp collecting, also known as philately, is the study of postage stamps, stamped envelopes, postmarks, postcards, and other materials relating to postal delivery.</p>
</section>
<section aria-label="Start a stamp collection">
<h2>How do I start a stamp collection?</h2>
<h3>Required equipment</h3>
<p>...</p>
<h3>How to acquire stamps</h3>
<p>...</p>
<h3>Organizations you can join</h3>
<p>...</p>
</section>
</main>
リスト
HTMLリストは、互いに類似したアイテムを意味的にグループ化して固有の意味を与える。
リストには次の3つがある。
不適切な例
<div>
<p>How do I start a stamp collection?</p>
<p>Equipment you will need</p>
<div>
<p>Small tongs with rounded tips</p>
<p>Stamp hinges</p>
<p>Stockbook or albumn</p>
<p>Magnifying glass</p>
<p>Stamps</p>
</div>
</div>
適切な例
<div>
<h1>How do I start a stamp collection?</h1>
<h2>Equipment you will need</h2>
<ol>
<li>Small tongs with rounded tips</li>
<li>Stamp hinges</li>
<li>Stockbook or albumn</li>
<li>Magnifying glass</li>
<li>Stamps</li>
</ol>
</div>
テーブル
テーブルは通常、データの整理やレイアウトに使用される。
レイアウト(テーブル)
レイアウトテーブルは一部の視覚的にリッチな電子メール、ニュースレター、広告などで使われる場合がある。その場合<th> や<caption>を用いて、関係を伝えたりコンテキストを追加してはならない。またテーブルレイアウトは、ARIA presentation role や aria-hidden stateを使用してATユーザーから非表示にする必要がある。
不適切な例
<table>
<caption>My stamp collection</caption>
<tr>
<th>[Stamp Image 1]</th>
<th>[Stamp Image 2]</th>
<th>[Stamp Image 3]</th>
</tr>
</table>
適切な例
<table role="presentation">
<tr>
<td>[Stamp Image 1]</td>
<td>[Stamp Image 2]</td>
<td>[Stamp Image 3]</td>
</tr>
</table>
データ(テーブル)
レイアウトテーブルとは異なり、データテーブルは全ての要素を公開する必要がある。
テーブルをアクセシブルにする最初のステップは <th>(見出しセル)と td(データセル)を使用すること。より複雑な場合は必要に応じて<rowgroup>、<colgroup>、<caption>、scope などを追加する。
不適切な例
<table>
<tr>
<td>Animal</td>
<td>Year</td>
<td>Condition</td>
</tr>
<tr>
<td>Bird</td>
<td>1947</td>
<td>Fair</td>
</tr>
<tr>
<td>Lion</td>
<td>1982</td>
<td>Good</td>
</tr>
<tr>
<td>Horse</td>
<td>1978</td>
<td>Mint</td>
</tr>
</table>
適切な例
<table>
<caption>
My stamp collection
</caption>
<tr>
<th>Animal</th>
<th>Year</th>
<th>Condition</th>
</tr>
<tr>
<td>Bird</td>
<td>1947</td>
<td>Fair</td>
</tr>
<tr>
<td>Lion</td>
<td>1982</td>
<td>Good</td>
</tr>
<tr>
<td>Horse</td>
<td>1978</td>
<td>Mint</td>
</tr>
</table>
ドキュメント
ページタイトル
<title>要素はユーザーが体験しようとしているページ、または画面のコンテンツを定義する。<h1>またはページのメイントピックに相当する。
SPA(Single-page app )ではmulti-page websitesのようにページ間を移動しないため、document.titleを書き換える必要がある。更新されたページタイトルをscreen readerに通知するためには追加の作業が必要になる場合がある。
ページタイトルを書くときは、最初に内部ページまたは重要なコンテンツを「front load」する。
不適切な例
<title>The Food Channel | Outrageous Pumpkins | Season 3 </title>
適切な例
<title>Season 3 | Outrageous Pumpkins | The Food Channel</title>
言語
ページの言語
ページ全体の言語(lang)を<html>に追加する。2文字のISO language codesが推奨される。
不適切な例
<html>...</html>
適切な例
<html lang="en">...</html>
またlangには、1 つの言語のみを関連付ける。
不適切な例
<html lang="ar,en,fr,pt,ja">...</html>
適切な例
<html lang="ja">...</html>
セクションの言語
ページ内のコンテンツごとに言語を切り替えることもできる。この場合<html>ではなく適切な要素にlangを追加する。
不適切な例
<html lang="en">
<body>
...
<div>
<p>
While traveling in Estonia this summer, I often asked, "Kas sa räägid
inglise keelt?" when I met someone new.
</p>
</div>
</body>
</html>
適切な例
<html lang="en">
<body>
...
<div>
<p>
While traveling in Estonia this summer, I often asked,
<span lang="et">"Kas sa räägid inglise keelt?"</span>
when I met someone new.
</p>
</div>
</body>
</html>
iframe
<iframe>は別のHTMLページ、またはページ内のサードパーティのコンテンツをホストする。
iframeで考慮すべき点
- 個別の
<iframe>コンテンツを持つそれぞれの親タグ内にタイトル要素を含める - ベストプラクティスとして、
<iframe>のscrollingをautoまたはyesに設定することを推奨
不適切な例
<iframe src="https://www.example.com"></iframe>
適切な例
<iframe title="Example Domain"
src="https://www.example.com"
scrolling="auto">
</iframe>
キーボードフォーカス
キーボードアクシシビリティの大部分はfocusを中心にしている。
フォーカスの順序
デフォルトのフォーカス順序はページの視覚的な順序と一致する必要がある。
Tabindex
フォーカスの順序は正のtabindex属性を持つ要素から始まり、tabindexが増大する方向に(1、2、3 など) に移動する。次にtabindexが0の要素をDOMの順序通りに移動し、tabindexが負の値の場合、フォーカスは当たらない。
ネイティブでフォーカス可能な要素でない要素に0以上のtabindexを設定する場合、追加のキーボードサポートが必要。
スキップリンク
冗長または役に立たないリンクのグループを飛び越える方法の1つにスキップリンクを追加する方法がある。スキップリンクはユーザーがコンテンツを飛び越えるアンカーリンクであり、ユーザーが最初に遭遇するフォーカス可能な要素として追加される。またデザインに応じてユーザーがタブ移動するまで非表示にすることも可能。
フォーカスインジゲーター
目に見えるフォーカスインジゲーターはユーザーがどこにいるのかを知らせる重要なツールである。
ブラウザのデフォルトスタイル
今日、すべての最新のWebブラウザーには、Webサイトまたはアプリのフォーカス可能な要素に、デフォルトのフォーカスインジゲーターが存在する。これを打ち消さないようにすることが重要。
不適切な例
a:focus {
outline: none; /* don't do this! */
}
適切な例
a:focus {
outline: auto 5px Highlight; /* for non-webkit browsers */
outline: auto 5px -webkit-focus-ring-color; /* for webkit browsers */
}
カスタムスタイル
カスタムスタイルのフォーカスインジケーターは、アウトライン、境界線、下線、ボックス、背景の変更などのように、色だけに依存しないさまざまな形を取ることが可能。
背景に対するコントラスト比。
フォーカスインジケーターは3:1の色のコントラスト比を維持することが推奨される。
フォーカス インジケーターのスタイル数に規則はないが、妥当な数に収める必要がある。
JavaScript
JavaScriptはアクセシビリティに大きな影響を与えうる。JavaScriptによるアクセシビリティの向上パターン、そしてJavaScriptフレームワークの使用における弊害とその解決策を共有する。
Trigger events
JavaScriptイベントは、ユーザーにインタラクティブなWebコンテンツを提供できる。一方でキーボードユーザーに対するサポートが必要となる。
例えばクリックイベントにおいて、<button>や<a>のようなセマンティックHTML要素を使用するとマウスやキーボード機能が自然と含まれるが、<div>のようなセマンティックでないHTML要素では、キーボード機能は自動で含まれない。
不適切な例
<div role="button" tabindex="0" onclick="doAction()">Click me!</div>
適切な例
<button onclick="doAction()">Click me!</button>
トリガーイベントに非セマンティックな要素を対象とする場合は、キーボード機能を自前で実装する必要がある。
ページタイトル
シングルページアプリケーション(SPA)の場合、ページタイトルの処理方法を検討する必要がある。
SPAの場合、document.titleは手動もしくはヘルパーパッケージ(JavaScript frameworkに依存したもの)などで追加出来る。
動的コンテンツ
JavaScriptを使用することで、開発者はユーザーの行動や振る舞いに基づいた動的なアプリケーションを生成できる。ただし使い方には注意が必要。
CSSの場合は、インラインスタイルの挿入よりもクラスの切り替えを優先する。JavaScript用いて動的にHTMLを挿入する場合、シンプルでアクセス可能である必要がある。
フォーカス管理
フォーカス管理とはフォーカスをどの範囲に閉じ込めるべきか、もしくは閉じ込めるべきでないかを管理すること。
コンポーネントレベル
キーボードトラップの作成。例えばモーダルにおいて、モーダルが開いている間、ユーザーのフォーカスをモーダルの外に出すべきではない。
ページレベル
ページ遷移時にもフォーカスの管理が必要である。特にSPAの場合、開発者がフォーカスをどこに移動するか決定する必要がある。
例えば以下のような方法が存在する。
-
aria-liveアナウンスでメインコンテンツにフォーカスをあてる - メインコンテンツまでスキップするために、フォーカスリンクに移動する
- 新しいページの最上位タイトルにフォーカスをあてる
状態管理
多くの場合、コンポーネントまたはページの状態はARIA属性を介して管理される(ARIA and HTML)。
コンポーネントレベル
コンポーネントに関する情報をユーザーに伝えるとき多くのARIA statesを考慮する必要があります。
一例
ARIA属性を使用するときは選択的であることが重要。どのクリティカルな情報をユーザーに伝えるべきか、考える必要がある。
ページレベル
ARIA live regionと呼ばれる視覚的に隠された領域を使用して、画面上の変更を伝え、支援技術ユーザーにアラートを送信することができる。これによってページ全体をリロードすることなく、ページの動的な変更をユーザーに通知できる。
JavaScriptはその動的な性質ゆえ、aria-liveとそのアラート領域のコンテンツを通知することに苦労してきた。コンテンツをDOMに非同期に追加すると、支援技術ユーザーが領域を取得するのが困難であり、コンテンツを適切に読み取るためには、ライブまたはアラート領域がロード時にDOMに存在する必要がある。
JavaScriptフレームワークを使用している場合、次のようなパッケージを備えてることがある。
- React:react-aria-liveやreact-a11y-announcer
- Angular:LiveAnnouncer
- Vue:vue-a11y-utils
画像
- 画像にアクセスできるコードの更新方法
- ユーザーに情報が共有されるべき時と場所
- ディスアドバンテージをもつ人々をサポートするために画像を改善するその他の方法
画像の目的とコンテキスト
まず画像がどのように、何のために使用されるのか考える必要がある。
→支援技術(AT)を通して人に情報を伝える方法の決定に役立つ。
alt属性決定木(An alt Decision Tree)のようなフローチャートも画像のカテゴリを決める手助けとなる。
装飾画像(Decorative images)
装飾画像は追加のコンテキストや、情報を追加しない画像である。装飾的な画像は補助的なものであり、内容ではなくスタイルを提供する場合がある。
画像が装飾である場合、ATから隠される必要があり、ATから隠す方法は以下のようにいくつか存在する。
ATから画像を非表示にする方法の例:
-
altを空にする - ARIA の使用
- 背景画像として使用する
<img src=“…” alt="" >
空またはnullの代替テキストは、alt属性の欠落と異なる。alt属性が欠落している場合、ATはファイル名もしくは周囲のコンテンツから画像に関する情報をユーザーに適用することがある。
<img src="..." aria-hidden="true" />
ロールをpresentationもしくはnoneに設定すると要素の狭んティクスがアクセシビリティツリーから削除される。一方でaria-hidden="true"は、要素全体と、その子要素もアクセシビリティAPIから削除される。
<!-- All of these choices lead to the same result. -->
<img src="..." role="presentation">
<img src="..." role="none">
<img src="..." aria-hidden="true">
aria-hidden="true"は、非表示にすべきでない要素を、非表示にする可能性があるので、使用には注意する。
background-image: url(“…”);
スクリーンリーダーはCSSの背景画像を検出できない。
情報を提供する画像(Informative images)
情報を提供する画像は、単純な概念、アイディア、感情などを伝える画像である。
画像が情報をもつ場合、プログラムチックな代替テキストを設定する必要がある。
<img>を使用した場合は、alt属性に代替テキストを含めることができる。
<img src="..." alt="..." >
インライン<svg>を使用する際には、アクセシビリティに注意が必要。
ATはデフォルトでSVGをスキップする。装飾的な場合は、それで問題ないが、情報画像を提供する場合、画像として認識できるようにrole=“img”を付与する必要がある。
また<svg>ではalt属性が使用できないため、代わりの方法を使用する。
<svg role="img">
<title>…</title>
</svg>
機能的な画像
機能的な画像は、アクションと結びつく。
例:
- ホームページにリンクするロゴ
- 検索ボタンの虫眼鏡
- 別のサイトやアプリに誘導するソーシャルメディアアイコン
情報を提供する画像と同様に、機能的な画像にも代替テキストが必要。情報を適用する画像とは異なり、機能的な画像は視覚的な情報ではなく、動作を説明する必要がある。
ロゴリンクの場合、altに代替テキストを使用するか、もしくは隠しテキストを使用する(CSSでテキストを隠す)方法がある。
<a href="/" target="_blank">
<img src="../logo.png" alt="Social bug network" />
</a>
<a href="/" target="_blank">
<span class="visually-hidden">Social bug network</span>
<img src="../logo.png" />
</a>
また以下の例ではtitle属性でアクションを、alt属性で画像の説明を伝えている。
<div title="Navigate to the homepage">
<a href="/">
<img src="..." alt="Lovely Ladybugs for your Lawn"></img>
</a>
</div>
複雑な画像
複雑な画像では、装飾的、情報的、または機能的な画像よりも多くの説明が必要になることがよくある。完全にメッセージを伝えるためには、短い代替説明、長い代替説明の両方が必要。
例:
- インフォグラフィック
- 地図
- グラフ / チャート
- 複雑なイラスト
<img src="…" alt="Diagram of the anatomy of a ladybug."><a href="ladybug-science.html">Learn more about the anatomy of a ladybug</a>
画像に説明を追加する方法の一つは、ページの後半にある説明へのジャンプリンク。
別の方法としてaria-describedby属性の使用もある。画像と説明の間に強力な関連付けを行うことができる。
<img src=“…” alt="Diagram of the anatomy of a ladybug." aria-describedby="description">
<p id="description">In this course, you will learn more about the anatomy of a ladybug, including the head, antenna, eye, pronotum, elytra, leg, abdomen, and wing.</p>
また<figure>と<figcaption>要素の使用もある。ARIA role="group"の追加は、<figure>要素のネイティブセマンティクスをサポートしていない古いブラウザの下位互換性を保証する。
<figure role="group">
<img src=“…” alt="Diagram of the anatomy of a ladybug.">
<figcaption>
<a href=“…”>Learn more about the anatomy of a ladybug</a>
</figcaption>
</figure>
代替テキストのベストプラクティス
当然ながら代替テキストは含めるだけでは、十分ではなく、テキストは意味のあるものでなければならない。
代替テキストは関連する視覚情報を取り込み、簡潔にする必要がある。スクリーンリーダーの文字数に制限はないが、通常は150文字以下を推奨する。より多くの説明が必要な場合は、複雑な画像のパターンを使用することも検討する。
代替テキストのベストプラクティスには次のようなものがある。
- スクリーンリーダーがファイルタイプを識別するため、「〇〇の画像」 / 「〇〇の写真」 などの言葉を避ける
- 画像ファイルに名付けをするときは可能な限り、一貫性があり正確な名付けを行う。画像名は代替テキストが欠落している時のフォールバックとなる
- 画像名や代替テキストに非アルファ文字 (#、9、& など)の使用は避ける。単語の間はアンダースコアではなくダッシュを使う
- 可能な限り句読点を使用する
- ロボットではなく人間のように代替テキストを書く。キーワードの詰め込みは避ける
色とコントラスト
知覚色
HSL(色相、彩度、明度)モデルはRGBの代替として作成された。より人間の認識に近い。
- 色相: 赤、緑、青などの色を質的に記述する方法で、0〜360の範囲
- 彩度: 色の強さで、0%~100% の範囲
- 明度: 色の明さで、0%(黒)~ 100%(白)の範囲
色のコントラストを測定する
色のコントラスト数式で、十分なコントラスト比を保つ。
色に焦点を当てたメディクエリ
メディアクエリの適用を検討する必要がある。
-
@prefers-color-scheme: ライト・ダークモード -
@prefers-contrast: 高コントラストのテーマ