PHPerでもわかる!
実践Webアクセシビリティ
2021/03/26 PHPerKaigi 2021
弁護士ドットコム株式会社
有木 詩織
自己紹介
● 有木 詩織 @shiori_pk
● 弁護士ドットコム株式会社
● サーバーサイドエンジニア
○ 基本PHP
○ たまにJavaScript
○ まれにHTML/CSS
目次
● 今からでも遅くない!Webアクセシビリティ入門
● Webアクセシビリティを意識した実装
● WAI-ARIA
● WAI-ARIAを用いた実装事例
はじめに
本トークのモチベーション
● PHPerでもHTMLやCSS、JavaScriptを書く機会は0ではない
● 自分が開発に携わっているサービスを、誰でも平等に多くのユーザーに
使ってもらいたい
本トークのゴール
● Webアクセシビリティをより高める実装方法の選択肢が増える
● Webアクセシビリティ完全に理解した
Webアクセシビリティをより高める実装方法の選択肢が増える
● Webアクセシビリティに絶対的な正解はないので、一つでも多く実装をする
方法の引き出しを増やす
● 実装をする際に何をどうやって実装するか自分で調べることができる
Web関連企業従事者のうち62%程度の人が、「知らない・聞いたことはあるが
内容は知らない」と回答
Webアクセシビリティ完全に理解した
https://www.cyberagent.co.jp/news/detail/id=25796
Webアクセシビリティ完全に理解した
https://twitter.com/kaitendaentai/status/1052689241744896001?s=20
今からでも遅くない!
Webアクセシビリティ入門
Webアクセシビリティとは
"The power of the Web is in its universality. Access by everyone
regardless of disability is an essential aspect."
(Webの力はその普遍性にあります。障害の有無に関わらず誰もがアクセスで
きるというのがWebの本質的な側面なのです。)
Tim Berners-Lee, W3C Director and inventor of the World Wide Web
Webへアクセスする手段・支援技術
● 手段
○ ビジュアルブラウザ
○ テキストブラウザ
○ ロボット など
● 支援技術
○ スクリーンリーダー
○ 拡大ツール
○ 点字ディスプレイ など
Webアクセシビリティの4つの原則
知覚可能
理解可能 堅牢
操作可能
WCAG
● Web Content Accessibility Guideline
○ Webコンテンツのアクセシビリティをより高めるためのガイドライン
○ 3つの達成基準
■ レベルA : 最低限の基準
■ レベルAA : 望ましい基準
■ レベルAAA : 発展的な基準
レベルA : 最低限の基準の例
● 知覚可能(1.x.x)
○ 利用者に提示されるすべての非テキストコンテンツには、同等の目的を果たすテキストに
よる代替が提供されている。(1.1.1 非テキストコンテンツ)
● 操作可能(2.x.x)
○ コンテンツのすべての機能は、個々のキーストロークに特定のタイミングを要することな
く、キーボードインタフェースを通じて操作可能である。ただし、その根本的な機能が利用
者の動作による始点から終点まで続く一連の軌跡に依存して実現されている場合は除
く。(2.1.1 キーボード)
レベルA : 最低限の基準の例
● 理解可能(3.x.x)
○ 入力エラーが自動的に検出された場合は、エラーとなっている箇所が特定され、そのエ
ラーが利用者にテキストで説明される。(
3.3.1 エラーの特定)
● 堅牢(4.x.x)
○ マークアップ言語を用いて実装されているコンテンツにおいては、要素には完全な開始タ
グ及び終了タグがあり、要素は仕様に準じて入れ子になっていて、要素には重複した属
性がなく、どの ID も一意的である。ただし、仕様で認められているものを除く。(
4.1.1 構
文解析)
Webアクセシビリティを
意識した実装
Webアクセシビリティを意識した実装
1. 要件に合った標準のHTML要素を適切に使用する
2. WAI-ARIAを使用する
標準のHTML要素を使用するメリット
● キーボードフレンドリー
○ 期待する操作がキーボードでもできる
● マシンフレンドリー
○ スクリーンリーダーなどの支援技術がページの構造を理解できる
● SEOフレンドリー
○ Google botなどのクローラーがページの構造を理解できる
標準のHTML要素を使用する例1
● キーボード操作でボタンにフォーカスを当てることができる
● Enter(return)キーによってボタンが持つ処理を実行できる
❌ <div>続きを見る</div>
⭕ <button type=“button”>続きを見る</button>
標準のHTML要素を使用する例2
● スクリーンリーダーやクローラーなどで見出しとして扱われる
❌ <p style=“font-size: 20px;”>これは記事の見出しです</p>
⭕ <h1>これは記事の見出しです</h1>
標準のHTML要素を使用する例3
● わざわざJavaScriptで window.location.href = “https://example.com” の
ようにしなくてよい
❌ <button type=“button”>次のページ</button>
⭕ <a href=“https://example.com”>次のページ</a>
Webアクセシビリティを意識した実装
1. 要件に合った標準のHTML要素を適切に使用する
2. WAI-ARIAを使用する
WAI-ARIA
本トークのゴール
● Webアクセシビリティを高める実装方法の選択肢が増える
● Webアクセシビリティ完全に理解した
WAI-ARIAとは
● Web Accessibility Initiative - Accessible Rich Internet Applications
○ 標準のHTMLの要素や属性で表現することができない意味論を、
HTMLの属性として付
与する
○ 3種類のHTML属性
■ ロール
■ プロパティ
■ ステート
Accessible Rich Internet Applications (WAI-ARIA) 1.2 日本語訳 : https://momdo.github.io/wai-aria-1.2/
ロール
● 要素が何か、何をするのかを定義する
● 時間またはユーザーアクションによって変化しない
● 検索やタブなどある程度決まったUIが多く含まれる
● 例
○ role=“tab”
○ role=“tooltip”
プロパティ
● 要素の性質や関連付けられたデータ値を表す
● 例
○ aria-required=“true”
○ aria-label=“ほげほげ”
ステート
● 要素のステート(状態)を表す
● 例
○ aria-disabled=“true”
○ aria-hidden=“true”
使用する際に気をつけること
● まずは標準のHTML要素で解決する
● 何でもかんでもWAI-ARIAを用いる必要はない
○ かえって誤用をするとWebアクセシビリティに悪影響を及ぼす
● 一部のOS・ブラウザ・スクリーンリーダーに対応していない
○ それぞれの組み合わせは複数あり、全てに対応するのは非現実的
WAI-ARIAを用いた実装事例
ツールチップ
一番最初に実装したもの
マウスホバー時 キーボード操作時
キーボードフォーカスを有効にする
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<span class="help_icon"></span>
<div>
<p>出張料金を.......</p>
</div>
</li>
</ul>
キーボードフォーカスを有効にする
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="help_icon"></button>
<div>
<p>出張料金を.......</p>
</div>
</li>
</ul>
WAI-ARIAの適用
role
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="help_icon"></button>
<div role="tooltip">
<p>出張料金を.......</p>
</div>
</li>
</ul>
aria-label
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="help_icon" aria-label="全国出張対応の説明"></button>
<div role="tooltip">
<p>出張料金を.......</p>
</div>
</li>
</ul>
aria-labelledby
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="help_icon" aria-labelledby="business_trip_description"></button>
<div role="tooltip">
<p id="business_trip_description">出張料金を.......</p>
</div>
</li>
</ul>
aria-describedby
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="help_icon" aria-describedby="business_trip_description"></button>
<div role="tooltip">
<p id="business_trip_description">出張料金を.......</p>
</div>
</li>
</ul>
aria-controls
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="hel_icon" aria-controls="business_trip_description"></button>
<div role="tooltip">
<p id="business_trip_description">出張料金を.......</p>
</div>
</li>
</ul>
⚠macOSのVoiceOverでは非対応
aria-expanded
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="help_icon" aria-expanded="true/false"></button>
<div role="tooltip">
<p>出張料金を.......</p>
</div>
</li>
</ul>
aria-haspopup
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button type="button" class="hel_icon" aria-haspopup="dialog"></button>
<div role="tooltip">
<p id="business_trip_description">出張料金を.......</p>
</div>
</li>
</ul>
どのaria-*属性を使うべきか
● 要件に応じて適切なaria-*属性を選択する
● 必ずしもすべてのaria-*属性を使用する必要はない
● あくまでもよりアクセシブルにするための手段の一つ
● 正解はない(と、思う)
○ 使い方の間違いはめっちゃあるのでしっかり理解して使う
完成(≠正解)
<ul>
<li>
<label for="business_trip">
<input type="checkbox" id="business_trip" name="bussiness_trip">
<span>全国出張対応</span>
</label>
<button
type="button"
class="help_icon"
aria-label="全国出張対応の説明"
aria-expanded="false"
aria-controls="business_trip_description"
>
</button>
<div role="tooltip">
<p id="business_trip_description">出張料金を請求する場合でも設定することができます。ユーザー側には「出張には別途料金が
かかる場合がございます。」と注記されます。
</p>
</div>
</li>
</ul>
おわりに
Webアクセシビリティを
高める実装に正解はない
が、出来ることはたくさんある
本トークのゴール
● Webアクセシビリティを高める実装方法の選択肢が増える
● Webアクセシビリティ完全に理解した

PHPerでもわかる!実践Webアクセシビリティ