この記事は、アクセシビリティについて知らない人が Web サービスをどうやってアクセシブルなものにするかを考察したまとめです。私と同じように「アクセシビリティって何?」というレベル感の方が対象読者です。
Web サイトにおけるアクセシビリティとは
最近よく耳にする「アクセシビリティ」とは何でしょうか?
いろいろなアクセシビリティ関連のサイトで説明されていますが、要約すると「誰でもがサイトのコンテンツをストレスなく閲覧・利用できるようにする事」のようです。Web アクセシビリティは略字で a11y と記載される事もあります。
Web サイトにはさまざまな人が訪れます。中には色弱やてんかん発作などがあり視覚的効果に敏感なユーザーがいるかもしれません。グワングワンするアニメーションや過度にビビッドな色合いが彼らにストレスを与えていないでしょうか?マウスを使えないユーザーがキーボード操作だけで他のユーザーと同じようにサイトを利用する事ができるでしょうか?いろいろなサイトを見ていると、そんな質問が投げかけられます。
そんな情報ばかり見ていると障害を持つ人達をターゲットにした特別な配慮のように取られがちですが、どうも本質はそうではないようです。アクセシビリティとは、ストレス軽減に配慮したサイトを提供する事で 誰でもが快適にサイトを利用できる よう品質を向上させる事にあります。キーボード操作の網羅性は、操作に長けたパワーユーザーやスクリーンリーダーの利用者にとって便利なものになります。また正しい HTML 構造とラベル付けは、開発者にとってセマンティクスなコーディングの意識付けとなります。さらには余分なモーションを減らす事で、視覚的な気持ち悪さを感じてサイトを離脱するユーザーを減らす事ができるかもしれません。
アクセシビリティに関するルール(ガイドラインやコーディング方法)は多岐に渡り、全てを実践する事はとても難しいものです。そこで、目的や手段を整理しアクセシビリティへの配慮がエンジニアの日常的な習慣となるよう、まずはその入口に立ちたいと思っています。
2021年9月現在、W3C による Web アクセシビリティに関するガイドラインは Ver2.1 が策定されています。
Web Content Accessibility Guidelines 2.1(日本語訳)
誰のためのアクセシビリティか
アクセシビリティの本質が 誰でもが快適にサイトを利用できる 事であるならば、サイトを訪れる全てのユーザーにおける多様性に配慮しなければいけないのではないか?アクセシビリティについて調べた中で、私が一番難しく感じたポイントはここでした。
TOKYO 2020 のサイトでもウェブアクセシビリティ方針を下記のように提示しています。
本ウェブサイトも、人種、肌の色、性別、性的指向、言語、宗教、政治、障がいの有無などにかかわらず、誰もが情報にアクセスできることを目指し、「ウェブコンテンツ・アクセシビリティ・ガイドライン(WCAG)2.1」に対応することを目標として、アクセシビリティの向上に取り組んでいます。
何らかの補助機能を利用している人達、幼児から高齢者までさまざまな年齢層の人達、さまざまな言語、性別、デバイス、文化圏、思想...。それら全てを考慮する事は至難の業です。また、アクセシビリティに配慮するあまり補助的な機能に手間をかけすぎる事は Web サービス開発にとってオーバースペックともなり得ます。
アクセシビリティについて調べ始めると、多種多様な見解がありベストプラクティスが多様化している事が分かります。フォントサイズひとつ取っても、推奨するサイズを定めているものもあれば、相対指定をベストプラクティスとするものもあり、フォントサイズを拡大した時にレイアウト崩れを発生させないようズームなど拡大機能を起点に考えるものもあります。
私達の作った Web サイトはどのようなユーザーによってどのように利用されているのでしょうか。病院や食材配送サービスのように幅広い年代層が訪れるサイトであれば、高齢者でも操作がしやすいよう配慮する必要があるかもしれません。身体面をサポートする器具やサービスを扱うサイトであれば、スクリーンリーダーやキーボード操作の網羅性が重要になるかもしれません。反対に写真の加工サービスなど視覚的効果に特化したサイトであれば、細かい操作をスクリーンリーダー向けに手厚く配慮するよりもサービスの目的を伝えるほうがサイト訪問者にとって有益となるかもしれません。
誰にでも読みやすいテキストを意識してフォントサイズを可能な限り大きくした結果テキストが枠から溢れてしまったり、画面が異様に間延びしてサービスの使い勝手が悪くなってしまっては本末転倒です。
まずは Web サイト(サービス)をどのように利用して欲しいのかという原点に、開発者である私達自身が立ち戻る必要があります。それによってどのようなユーザーに手厚い配慮が必要なのかを見極め、自分たちにできるミニマムなスタートを切る。私はそこがアクセシビリティ配慮の入り口なのではないかと考えています。
参考ドキュメント
- アクセシビリティ | MDN
- WCAG 2.0 達成方法集 日本語訳
- WCAG 2.1 達成方法集 日本語訳
- WAI-ARIA オーサリング・プラクティス 1.1 日本語訳
- WAI-ARIA オーサリング・プラクティス 1.2 英語原文
- Accessible Rich Internet Applications (WAI-ARIA) 1.1 日本語訳
- Accessible Rich Internet Applications (WAI-ARIA) 1.2 日本語訳
- Accessibility Developer Guide
この記事について
この記事で紹介している実践方法は Web アクセシビリティ入門としての簡易なものであり、完璧なガイドライン準拠をゴールとするものではない事をご了承ください。またサンプルコードの「Bad/Good」は要点を見やすくしたもので、コピペで使えるベストプラクティスではありませんのでご注意ください。
1. 基本的な実践方法
この章では、日常的に開発に取り入れる事ができるいくつかの簡易な実践方法を紹介します。
文章構造のメタデータを設定する
HTML の head
は文章構造のメタデータの集まりです。表立って見えないものが多いですが、サイトをマシンリーダブルなものにするために重要な要素と言えます。簡単なサンプルコードで例を見てみましょう。
<!-- 😩 Bad -->
<html>
<head>
</head>
</html>
- 何も設定されていない。
<!-- 😩 Bad -->
<html>
<head>
<title>お得な\(^o^)/通販サイト★彡</title>
</head>
</html>
- 顔文字など視覚的効果に依存した記号が使われている。
<!-- 😩 Bad -->
<html>
<head>
<title>株式会社ほげ</title>
</head>
</html>
- サイトの利用用途が不明。
<!-- 😊 Good -->
<html lang="ja">
<head>
<title>エンジニア採用情報 | 株式会社ほげ</title>
</head>
</html>
-
lang
がサイト内の言語を示している。 -
title
がサイトの利用用途を示している。
lang
属性はサイトの言語を明示的にする事でスクリーンリーダーの発音に影響します。title
はサイトのページの目的をユーザーに伝える他、ブックマークのタイトル設定にも使われます。
- H25: title 要素を用いて、ページタイトルを提供する
- H57: html 要素の言語属性を使用する
- H58: 自然言語の変更を指定するために、言語属性を使用する
- G88: ウェブページに説明的なタイトルを提供する
また、アクセシビリティのガイドラインには登場しませんが Google 検索などの結果表示に使われる description
もサイトの目的を伝えるマシンリーダブルな情報であると言えます。このようにメタデータを正しく設定する事はサイトを訪れるユーザーに有益なものとなります。
<html>
<head>
<title>カメラ屋トップページ</title>
<meta name="description" content="写真のデジタルデータを販売するショップです。">
</head>
</html>
基準となるフォントサイズを決める
rem
は html タグのフォントサイズを基準とした相対指定です。html タグにフォントサイズの指定がなければブラウザで設定されたフォントサイズが適用されます。
Chrome の設定ではデフォルトで「フォントサイズ(中)」となっており、この設定では 16px が適用されます。font-size: 2rem
は 32px、font-size: 0.5rem
は 8px となります。
<h1>ページ見出し</h1>
<p>テキスト</p>
<button>ボタン</button>
<style>
/* フォントサイズ中の場合 16px が適用される */
html { }
/* 基準の 2 倍 ===> 32px */
h1 { font-size: 2rem; }
/* 基準と同じ ===> 16px */
p { }
/* 基準の半分 ===> 8px */
button { font-size: 0.5rem; }
</style>
基準となるフォントサイズを変更するには html タグにフォントサイズを指定します。
/* 基準を 20px に設定 */
html { font-size: 20px; }
/* 基準の 2 倍 ===> 40px */
h1 { font-size: 2rem; }
/* 基準と同じ ===> 20px */
p { }
/* 基準の半分 ===> 10px */
button { font-size: 0.5rem; }
デバイスにより基準となるフォントサイズを変更したい場合はメディアクエリを使います。
/* タブレット */
@media (min-width: 768px) {
html { font-size: 16px; }
h1 { font-size: 2rem; } /* 32px */
}
/* PC */
@media (min-width: 1280px) {
html { font-size: 18px; }
h1 { font-size: 2rem; } /* 36px */
}
親要素のフォントサイズを起点とする場合は em
や %
を使用します。
<div>
<p>テキスト</p>
<span>テキスト</span>
</div>
<style>
div { font-size: 30px; }
div > p { font-size: 50%; } /* 15px */
div > span { font-size: 0.5em; } /* 15px */
</style>
rem
em
%
の相対指定によるメリットは、ユーザーが任意に設定したフォントサイズに応じて変化する事です。絶対指定の px
pt
はブラウザの設定に関わらず全てのユーザーに対して同じフォントサイズが適用されます。
/* ブラウザの設定によりフォントサイズが決まる */
html { }
/* 【相対指定】 ブラウザの設定に応じて変化する */
div { font-size: 1rem; }
/* 【絶対指定】 ブラウザの設定に関わらず 10px が適用される */
p { font-size: 10px; }
相対指定のデメリットは、思わぬレイアウト崩れを引き落こす可能性がある事です。フォントサイズの拡大縮小によりレイアウトが著しく崩れる場合は ...
を使った省略表記や、文字数に影響しないグリッドレイアウト、絶対指定のフォントサイズを検討したほうが良いかもしれません。
/* フォントサイズによりレイアウトが変わってしまう */
.sidebar { width: 10rem; }
/* 親要素が固定幅の場合、フォントサイズが大きすぎると見切れてしまう */
.icon { font-size: 0.5rem; }
MDN を始めガイドライン準拠を促す解説としては相対指定を推奨するほうが多いように思います。ただ、ガイドラインに準拠したルールの徹底よりも見やすいサイトやサービスを提供する事のほうがユーザーにとって有益であり「よりストレスが少ない」という視点で基準となるフォントを決定する事が重要だと考察します。
- C12: フォントサイズにパーセントを使用する
- C14: フォントサイズに em 単位を使用する
- C24: コンテナのサイズに CSS のパーセント値を使用する
- G204: 閲覧画面の幅を狭めたときに、ユーザエージェントによるテキストのリフローを妨げない
背景色と比較してはっきり見える文字色を使う
ソフトな印象を与えるために同系色でまとめた色合いは、色の識別が困難なユーザーにストレスを与える事があります。
<!-- 😩 Bad -->
<div style="background: white;">
<p style="color: lightgray;">...</p>
</div>
- コントラストが低く文字が背景色に埋もれて見える。
- アクセシビリティのガイドラインでは
4.5:1
以上のコントラストが必要とされる。
<!-- 😊 Good -->
<div style="background: white;">
<p style="color: black;">...</p>
</div>
- コントラストが上がり文字がはっきり見える。
- 色を識別できないユーザーに情報が伝わる。
また、背景と比較してはっきり見える色を使っていても色の識別が困難な場合もあります。例えば、下記の緑・青・赤はグレースケールにおいて同じような色合いに見えてしまいます。
<p style="background:#1ea6a1;">green</p>
<p style="background:#4287f5;">blue</p>
<p style="background:#eb684b;">red</p>
色だけに頼った表現は一部のユーザーには伝わりません。
<p style="background:#1ea6a1;">商品 A</p>
<p style="background:#4287f5;">商品 B</p>
<p style="background:#eb684b;">商品 C</p>
このような場合は色に加えて視覚的な手がかりを提供します。
<ul>
<li><p style="background:#1ea6a1;">在庫多数</p>商品 A</li>
<li><p style="background:#4287f5;">在庫あり</p>商品 B</li>
<li><p style="background:#eb684b;">在庫切れ</p>商品 C</li>
</ul>
コントラストの基準は、標準より大きいフォントサイズを使用した場合は 4.5:1
よりも緩和されます。人間がルールを覚えているのは大変なので Chrome エクステンションの Lighthouse などを利用してガイドライン準拠をチェックすると便利です。また Chrome エクステンションの Grayscale Tool などが利用してグレースケールでどのように見えるのかをチェックするのも良いでしょう。
- G18: テキスト (及び文字画像) とその背景の間に、少なくとも 4.5:1 のコントラスト比を確保する
- G14: 色の違いで伝えている情報をテキストでも入手可能にする
- G111: 色とパターンを併用する
- G138: 色の手がかりを用いるときは必ず、セマンティックなマークアップを使用する
- G145: テキスト (及び文字画像) とその背景の間に、少なくとも 3:1 のコントラスト比を確保する
- G148: 背景色及び文字色を指定せず、その初期設定を変更するウェブコンテンツ技術の機能を使用しない
- G156: テキストのブロックの前景及び背景を変更できる、一般に入手可能なユーザエージェントが備えるウェブコンテンツ技術を使用する
- G174: 利用者が十分なコントラストのある提示に切り替えられるように、十分なコントラスト比のあるコントロールを提供する
- G175: 背景色及び前景色のための複数色選択ツールをページ上で提供する
- G182: 文字色の違いが情報を伝えるために使用される場合に、利用可能な追加の視覚的な手がかりを確保する
- G183: 色が単独でリンク又はコントロールを特定する場所で、周囲のテキストと一緒に 3:1 のコントラスト比を使用し、そのリンク又はコントロールのフォーカスに追加の視覚的な手がかりを提供する
- G205: 色のついたフォームコントロールのラベルに対して、テキストによる手がかりを含める
要素にフォーカスしている事が分かるようにする
input
textarea
などの HTML の要素はクリックやタブキー移動でフォーカスを持つ事ができます。フォーカスを持った状態ではブラウザ標準のフォーカスリングが表示されますが、見栄えを悪くするという理由で開発者が意図的にフォーカスリングを見えなくしてしまう事があります。
<!-- 😩 Bad -->
<button style="outline:none">...</button>
- キーボード操作でボタンにフォーカスした時、状態が視覚的に伝わらない。
- マウスなどポインティングデバイスを利用できないユーザーが現在位置を見失ってしまう。
キーボード操作のみでブラウザと対話するユーザーは現在位置を知るためにフォーカスリングが重要な手がかりとなります。体裁を保つには CSS でフォーカスリングの外観を整えるほうが得策です。
<!-- 😊 Good -->
<button>...</button>
<style>
button:focus {
box-shadow: 0 0 2px 1px green;
}
</style>
また複雑な UI や装飾のために <div>
を使うようなケースでは、タブキーによる移動ができません。インタラクティブな要素であればタブキー移動を考慮し tabindex
を 0 以上の値に設定します。
<!-- 😩 Bad -->
<div class="menu-item">...</div>
- 装飾のために
<div>
タグを使うような例。 - キーボード操作でクリックする事ができない。
<!-- 😊 Good -->
<div class="menu-item" tabindex="0">...</div>
- キーボード操作で
<div>
にフォーカスできるようになる。
参考サイトとして Focusable Elements にデバイスと HTML 要素のフォーカスの関連がまとめられています。いろいろなデバイスでどのようにフォーカスを受け付けるのか参考にしてみても良いかもしれません。
- G149: フォーカスを受け取るときに、ユーザエージェントによって強調されるユーザインタフェース コンポーネントを使用する
- G165: 視認性の高いデフォルトのフォーカスインジケータが引き継がれるように、プラットフォームデフォルトのフォーカスインジケータを使用する
- G195: コンテンツ制作者が提供する視認性に優れたフォーカスインジケータを使用する
- G202: すべての機能に対してキーボード制御を確保する
HTML 標準のタグを使用する
複雑な UI パーツの実現のために HTML 標準のタグを使わず <div>
や <span>
を使って装飾を施すようなケースがあります。このような場合、本来使うべきタグの排除によってその意味合いまで失う事に注意が必要です。
<!-- 😩 Bad -->
<div class="entry-form">
<div class="form-group">
<span>メール</span>
<input class="email-address">
</div>
<div class="submit-button">登録</div>
</div>
- 視覚効果のみに依存しておりマシンリーダブルでない。
- スクリーンリーダーの利用ユーザーが全く操作できない。
<!-- 😊 Good -->
<form method="POST" action="...">
<fieldset>
<legend>メール</legend>
<input type="email">
</fieldset>
<button type="submit">登録</button>
</form>
<style>
legend { color: blue; }
form button { padding: 5px; }
</style>
- HTML の要素の役割が明確でマシンリーダブルになる。
- Enter キーによる submit などキーボードで操作可能になる。
- Enter キーと submit はフォームに共通した挙動でユーザーが操作を推測しやすい。
HTML 標準のタグを使用する事により、そのタグの意味合いとキーボード操作が暗黙的に付随するメリットがあります。この事により要素にフォーカスした時、それがどのような目的を持ちどのような操作ができるのかをスクリーンリーダーの利用ユーザーに伝える事ができるようになります。
- H88: 仕様に準じて HTML を使用する
- G108: 名前 (name) 及び役割 (role) を公開し、利用者が設定可能なプロパティを直接設定可能にして、変化の通知を提供するために、マークアップを用いる
- G115: 構造をマークアップするために、セマンティックな要素を使用する
ページの構造をアウトライン化する
HTML 標準のタグは入力コントロールだけでなく、ページの構造に関するものも存在します。これらは input
や button
など入力コントロールと同様に、タグそのものに意味合いを持ちます。
<!-- 😩 Bad -->
<div class="page-title">エンジニアブログ</div>
<div class="page-navigation">
<a>サイトトップ</a>
<a>採用サイト</a>
</div>
<div class="main-contents">
<div>2021/01/01<br>...</div>
<div>2021/01/02<br>...</div>
</div>
- 視覚効果のみに依存しておりマシンリーダブルでない。
<!-- 😊 Good -->
<h1>エンジニアブログ</h1>
<header>
<nav>
<a>サイトトップ</a>
<a>採用サイト</a>
</nav>
</header>
<main>
<article><h2>2021/01/01</h2>...</article>
<article><h2>2021/01/02</h2>...</article>
</main>
- DOM の要素の役割が明確でマシンリーダブルになる。
表立って見えないものでも HTML 標準のタグは積極的に取り入れていきましょう。ページ構造に関するタグは MDN で コンテンツ区分 として紹介されています。また <h1>
〜 <h6>
の 見出し要素 も次の見出しが現れるまでの範囲において暗黙的にアウトラインを生成するため、ページ構造において重要な役割を果たします。
参考として、Chrome エクステンションの HTML Visual Validation を利用するとアウトラインを形成する主要なタグを可視化する事ができます。
- H42: 見出しを特定するために、h1 要素~ h6 要素を使用する
- H69: コンテンツの各セクションの開始位置に見出し要素を提供する
- G140: 異なる提示を可能にするために、情報と構造を表現から分離する
- G141: 見出しを用いてウェブページを構造化する
入力項目をラベル付けする
input
など HTML 標準のタグを使った場合、それがテキスト入力を受け付ける入力コントロールである事はユーザーに伝わります。ただし「何のための入力であるか」は伝わらないため、ラベルを使って補足します。
<!-- 😩 Bad -->
<span>ユーザー名</span>
<input type="text">
- 何のための入力要素なのか、スクリーンリーダーの利用ユーザーに伝わらない。
<!-- 😊 Good -->
<label for="username">ユーザー名</label>
<input type="text" id="username">
-
<input>
にフォーカスした時スクリーンリーダーがラベルを読み上げる。
<label>
を使った場合、ラベルのクリックによって <input>
がアクティブになります。ヒット領域領域を拡大する事で小さなデバイスでも操作しやすくなり、操作性も向上します。
- H44: テキストラベルとフォームコントロールを関連付けるために、label 要素を使用する
- G131: 説明的なラベルを提供する
- G162: 関係性を最大限に予測できるようにするためにラベルを配置する
- G167: テキストフィールドの目的をラベル付けするために隣接するボタンを用いる
意味の通るテキストラベルを用いる
<a>
はその要素のテキストがラベルの役割を果たす特性を持っていますが、テキストだけでは説明が不十分な場合があります。
<!-- 😩 Bad -->
このサイトについては <a href="...">ここをクリック</a> してください。
もっと詳しく知りたい方は <a href="...">こちら</a>
- リンクテキストが前後の文脈に依存している。
- リンクテキストをスクリーンリーダーが単独で読み上げた時、ユーザーに意図が伝わらない。
<!-- 😊 Good -->
<a href="...">このサイトについての情報</a>
<a href="...">関連情報</a>
- リンクテキスト単独で意図が伝わるものになる。
ガイドラインでは、リストや見出しが <a>
を内包する事で短いリンクテキストでも目的が特定できるテクニックが紹介されています。テキストが長くなる事を避けたい場合はこのような方法も検討できます。
- G13: コンテキストの変化を引き起こすフォームコントロールへの変更が行われる前に、何が起こるのかを説明する
- H77: リンクテキストとそれが含まれているリスト項目とを組み合わせて、リンクの目的を特定する
- H80: リンクテキストと先行する見出し要素とを組み合わせて、リンクの目的を特定する
- G91: リンクの目的を説明したリンクテキストを提供する
画像の意味を補足する
画像は用途をイメージしやすくするための補足表現として使われる他に、主目的を説明するための表現としても使われます。画像を使う場合は alt
属性でその意味を補足します。
<!-- 😩 Bad: 画像で大きさの比較を提示するような例 -->
<img src="ボルボックス.png">
<img src="ナベカムリ.png">
<img src="ツリガネムシ.png">
- スクリーンリーダーの利用ユーザーに伝わらない。
<!-- 😊 Good -->
<img src="ボルボックス.png" alt="0.4から0.9ミリ程度の大きさ">
<img src="ナベカムリ.png" alt="0.07から0.1ミリ程度の大きさ">
<img src="ツリガネムシ.png" alt="0.025から0.05ミリ程度の大きさ">
ガイドラインでは本文が画像の意図や説明を兼ねている場合は alt
属性を空として良いとされています。
<section>
<h2>ボルボックス</h2>
<img src="ボルボックス.png" alt="">
<p>0.4から0.9ミリ程度の大きさ</p>
</section>
<section>
<h2>ナベカムリ</h2>
<img src="ナベカムリ.png" alt="">
<p>0.07から0.1ミリ程度の大きさ</p>
</section>
<section>
<h2>ツリガネムシ</h2>
<img src="ツリガネムシ.png" alt="">
<p>0.025から0.05ミリ程度の大きさ</p>
</section>
- H67: 支援技術が無視すべき画像に対して、img 要素の alt テキストを空にして、title 属性を付与しない
- G100: 非テキストコンテンツの一般に認められた名前 (name) 又は説明的な名前となる簡潔なテキストによる代替を提供する
- G143: CAPTCHA の目的を説明するために、テキストによる代替を提供する
- G144: 異なるモダリティを用いて同じ目的を果たす、もう一つの CAPTCHA がウェブページに含まれていることを確認する
- G196: 画像のグループにある一つの画像に、そのグループのすべての画像を説明するテキストによる代替を提供する
視覚的な意味のみを持つテキストを避ける
例えばアルファベットの X
というテキストをダイアログの閉じるボタンに適用した場合、バツ印を連想させるため視覚的な意味を持つといえます。ところがスクリーンリーダーの利用ユーザーには意味不明なアルファベットが読み上げられてしまいボタンの用途を伝える事ができなくなります。
<!-- 😩 Bad -->
<dialog>
<button>X</button>
</dialog>
このようなケースでは「閉じる」「戻る」「キャンセル」などのテキストのほうが適していると言えるでしょう。
<!-- 😊 Good -->
<dialog>
<button>閉じる</button>
</dialog>
OS の設定に応じてアニメーションを減らす
しばしば、ロゴ・写真・図形などに動きを加えたモーショングラフィックスや、写真のカルーセル表示など、リッチなビジュアル表現をするサイトを見かけます。一方で連続して動くアニメーションにめまいや不快感を感じるユーザーがいる事に配慮が必要です。
macOS では「視覚効果を減らす」Windows では「アニメーションを表示する」という OS の設定の切り替えによってモーションの表示方法を変更する事ができます。CSS や JavaScript を使ったアニメーションはこの設定に自動で連動しないため、設定に応じた切り替えを開発者が用意する必要があります。
<!-- CSS のアニメーションを OS の設定に応じて切り替える例 -->
<div class="animation box">hello</div>
<style>
.box {
width: 5rem;
padding: 0.5rem;
border-radius: 10px;
text-align: center;
}
@keyframes fadeIn {
from { color:white; }
to { background:black; color:white; }
}
/* OS の設定でモーションを無効化している時 */
@media (prefers-reduced-motion: reduce) {
.animation { animation: none; }
}
/* OS の設定でモーションを有効化している時 */
@media (prefers-reduced-motion: no-preference) {
.animation {
animation: 3s linear 2s infinite alternate fadeIn;
}
}
</style>
同じ CSS を利用して、カルーセル表示でも OS の設定に応じて自動再生とユーザーによる手動再生を切り替える事ができます。
<div class="carousel">
<img src="...">
<img src="...">
<img src="...">
<div class="carousel-control">
<button>開始</button>
<button>終了</button>
</div>
</div>
<style>
/* OS の設定でモーションを無効化している時は操作パネルを表示 */
@media (prefers-reduced-motion: no-preference) {
.carousel-control { display:none; }
}
</style>
- G4: コンテンツを一時停止させて、一時停止させたところから再開できるようにする
- G11: 5 秒未満で点滅するコンテンツを制作する
- G176: 閃光を放つ領域を十分に小さくする
- G186: 動きのあるコンテンツ、点滅するコンテンツ、又は自動更新するコンテンツを停止させるコントロールを使用する
- G187: ユーザエージェントによって点滅するコンテンツを停止できるウェブコンテンツ技術を使用する
- G191: 点滅するコンテンツのないページを再読み込みするリンク、ボタン、又はその他のメカニズムを提供する
解像度の異なるデバイスからのアクセスを考慮する
「レスポンシブ」という言葉が Web サイトのデファクトの手法になりつつある昨今ですが、アクセシビリティ配慮としても大事な視点です。
/* 😩 Bad */
ul { width: 300px; }
main { font-size: 14pt; }
img { width: 500px; }
- スマホなど解像度の低いデバイスでフォントサイズが小さく読みづらい。
- スマホなど解像度の低いデバイスで画像が見切れてしまう。
/* 😊 Good */
/* タブレット */
@media (min-width: 768px) {
ul { display: none; }
main { width: 100vw; }
img { width: 80%; }
}
/* デスクトップ PC */
@media (min-width: 992px) {
ul { width: 30vw; }
main { width: 70vw; }
img { width: 500px; }
}
- デバイスごとに表示が最適化される。
どのようなデバイスを使ってサイトを訪れるのかはユーザーに委ねられています。開発環境と異なる解像度のデバイスをエミュレートし、操作性を損なう事がないかチェックする必要があります。
メジャーなブラウザであればデバイスのエミュレートは標準の機能として提供されています。また異なるデバイスを一度にエミュレートするツールとして Responsively がとても便利でおすすめです。
- 達成基準 1.3.4 の失敗例 - デバイスの向きを変更するように促すメッセージが表示される
- 達成基準 2.5.6 の失敗例 - タッチスクリーンデバイスにおいてインタラクションがタッチのみに限定されている
中には、さまざまなグラフと多数の入力コントロールを一度に表示するなど、レスポンシブの実現が難しいサイトがあるかもしれません。スマホ表示のための特別なサイトを数ヶ月かけて作ったとして、結果的に利用ユーザーが一人もいないのであれば悲しい自己満足になってしまいます。また、レイアウト崩れを考慮して特定のデバイスで画面全体を縮小表示するような場合、フォントサイズやボタンが小さくなりすぎる事で操作性との兼ね合いの問題が出てきます。
私が まずは Web サイト(サービス)をどのように利用して欲しいのかという原点に立ち戻る 事を重要と考えているのは、世界中のユーザーと利用シーンを網羅した Web サイト構築の難しさが根底にあるからです。アクセシビリティ配慮に傾倒するあまり本来のユーザーを見失う事は、開発者・ユーザーどちらにとっても嬉しい事ではありません。
このページで紹介した実践方法も、ご自身のサイトに適用する際に「誰に対してメリットがあるのか?」をご一考いただければと思います。
2. WAI-ARIA とは
この章では Web アクセシビリティで避けて通れない WAI-ARIA についておおまかに説明します。
Web アプリケーションは、ひと昔前と比較してリッチな UI が当たり前の時代となりつつあります。複雑な UI パーツも次々と登場し <div>
や <span>
を多用した複雑な構造がよく見られるようにもなりました。このような構造は <form>
や <fieldset>
などを使ったシンプルなアプローチと比べると装飾を華やかにする事には長けていますが、HTML のコードでは構造上の意味を持ちません。スクリーンリーダーの利用者にとって、このようなサイトは足がかりが掴めずとてもストレスを感じるものとなります。
WAI-ARIA は要素に付加的な意味を追加する事でマシンリーダブルを実現し、ユーザーを手助けする事を目的としています。WAI-ARIA では意味を HTML タグの属性として定義します。これらの属性は「ロール」「ステート」「プロパティ」に分類できます。
ロール
ロールは要素に対して役割を定義します。例えば <div>
にロールを付与する事で、その要素がサイト上の特定の意味を持つ領域である事を示します。
<!-- ダイアログである事を示す -->
<div role="dialog">
<h2>規約</h2>
<p>...</p>
<button>同意する</button>
</div>
ロールの分類
ロールはいくつかの種類に分類されます。
ロール | 用途 | 例 |
---|---|---|
抽象ロール | ロールモデルの定義に使用されるもので開発者は使用しない |
command landmark
|
ウィジェットロール | 単体または複合のウィジェットとして機能する事を示す |
button tab listbox
|
文章構造ロール | コンテンツを体系づける構造記述を示す |
article feed
|
ランドマークロール | 特定の目的に関連した領域である事を示す |
form search
|
ライブ領域ロール | 動的に変化するコンテンツである事を示す |
alert timer
|
ウインドウロール | ウインドウとして機能する事を示す | dialog |
ロールの種類
ロールにはたくさんの種類があります。
checkbox
や form
など HTML 標準のタグで代用可能なものや、banner
menubar
など WAI-ARIA 独自のものがあります。
ステートとプロパティ
ステートは要素の状態を示します。例えば下記の例では、トグルボタンが押されている状態を示しています。
<div role="toolbar">
<button type="button" aria-pressed="true">Asc</button>
<button type="button" aria-pressed="false">Desc</button>
</div>
プロパティは要素の性質を示します。例えば下記の例では、入力が必須である事を示しています。
<div role="textbox" aria-required="true">
ステートとプロパティは HTML の要素の状態とは連動しません。トグルボタンを押した時 aria-pressed="false"
から true
に変更するなど、開発者が状態の変化に応じて値をセットする必要があります。
ステートとプロパティはロールの持つ性質を形成するために使用し、どちらも aria-
という属性名のプレフィクスを持ちます。特性が類似しているため WAI-ARIA のドキュメントでは「ステートおよびプロパティ」として両者をまとめて表記する箇所が多く見られます。
ステートおよびプロパティの定義 | WAI-ARIA 1.2
ロールとステート・プロパティの関係
要素のロールにより、その要素が持つべきステート・プロパティが決定します。またいくつかのロールは、要素の親子関係を持ちます。
<!-- tablist ロールは 複数の tab ロールを所有する -->
<div role="tablist" aria-label="商品カテゴリ">
<!-- tab ロールは aria-selected ステートを持つ -->
<button role="tab" aria-selected="true">靴</button>
<button role="tab" aria-selected="false">靴下</button>
</div>
ロールと一致しないステート・プロパティを指定する事や、親子関係を無視する記述は誤りです。
<!-- 😩 Bad: tablist ロールは aria-pressed を持たない -->
<div role="tablist" aria-pressed="true">
<!-- 😩 Bad: tab ロールが存在しない -->
</div>
暗黙の ARIA ロール
HTML 標準のタグはロールとの関連性を持ちます。
HTML タグ | 暗黙のロール | 変更可能なロール |
---|---|---|
<button> |
button |
checkbox link menuitem など |
<div> |
なし | すべてのロール |
<label> |
なし | なし |
<main> |
main |
なし |
<div>
は全てのロールに変更が可能です。
<!-- 😊 Good -->
<div role="button"></div>
<div role="list"></div>
<label>
はロールの宣言が許可されません。
<!-- 😩 Bad -->
<label role="button"></label>
<button>
は暗黙的に button
ロールが付与されます。
<!-- 暗黙的に button ロールが付与される -->
<button></button>
暗黙のロールを宣言する事は冗長とされています。
<!-- 😩 Bad -->
<button role="button"></button>
<!-- HTML 5 をサポートしないブラウザ向けにフォールバックとして利用される事はある -->
<main role="main"></main>
HTML タグとロールの関係は HTML要素ごとのARIA属性利用の規則 | ARIA in HTML の表組みの部分にまとめられています。
暗黙のステート・プロパティ
ロールを宣言した時と同じように、暗黙のロールはその要素が持つべきステート・プロパティを決定します。
<div role="heading" aria-level="1"></div>
<!-- 暗黙のロール: heading -->
<!-- 暗黙のプロパティ: aria-level -->
<h1></h1>
暗黙のステート・プロパティを宣言する事は冗長とされています。
<!-- 😩 Bad -->
<h1 aria-level="1"></h1>
HTML タグとステート・プロパティの関係は HTMLの機能によるARIA属性利用の規則 | ARIA in HTML の表組みの部分にまとめられています。
グローバルなステート・プロパティ
一部のステート・プロパティはロールの宣言に関わらず、全ての要素で利用可能です。
<!-- 😊 Good -->
<!-- aria-keyshortcuts でショートカットキーを明示する -->
<button aria-keyshortcuts="A">...</button>
ただしロールにより「禁止のステートおよびプロパティ」に列挙されている場合は利用できません。例えば caption ロール では aria-label
の使用が禁止されています。
<!-- 😩 Bad: 禁止されている -->
<div role="caption" aria-label="ツリガネムシ">...</caption>
グローバルなステートおよびプロパティ | WAI-ARIA 1.2
3. WAI-ARIA の属性の書き方
この章では WAI-ARIA を使い始めるための基本的な属性の書き方と注意点について紹介します。
できるだけ HTML 標準のタグを使う
WAI-ARIA のドキュメントでは ARIA無しのほうが、悪いARIAよりも良い とされています。
CSS で装飾された視覚的な手がかりと同じように、スクリーンリーダーの利用者は WAI-ARIA を手がかりにサイトのコンテンツを辿ります。WAI-ARIA の間違いによって、視覚的に表現しているものとは全く異なる意味合いを提供してしまう事に注意が必要です。
HTML 標準のタグを利用した場合、暗黙のセマンティクスにより視覚的な表現と WAI-ARIA は一致します。代替可能なものはできるだけ HTML 標準のタグを使いましょう。
<!-- HTML 標準のタグで代替可能 -->
<div role="checkbox" aria-checked="true"></div>
<!-- 😊 Good -->
<input type="checkbox">
<!-- 😩 Bad: 視覚的な表現と WAI-ARIA の表現がずれてしまう -->
<div role="checkbox"
aria-checked="false"
class="checkbox-check-on"
></div>
必須のステート・プロパティを必ず記述する
下記の例では heading
ロールを使用しています。ドキュメント の「必要とされるステートおよびプロパティ」は必ず記述するようにします。
<!-- 😊 Good -->
<div role="heading" aria-level="2">
<!-- 😩 Bad: 必須のプロパティ指定がない -->
<div role="heading">
<!-- 😩 Bad: 必須のプロパティの値の指定がない -->
<div role="heading" aria-level>
禁止されたステート・プロパティを記述しない
下記の例では code
ロールを使用しています。ドキュメント の「禁止のステートおよびプロパティ」を記述するのは誤りです。
<!-- 😊 Good -->
<div role="code">
console.log('Hello world!');
</div>
<!-- 😩 Bad: aria-label の記述はできない -->
<div role="code" aria-label="プログラミングコードの例">
console.log('Hello world!');
</div>
所有の関係を守る
下記の例では list
listitem
ロールを使用しています。ドキュメント の「必要とされる所有される要素」「必要とされるコンテキストロール」を必ず記述するようにします。
<!-- 😊 Good -->
<div role="list">
<div role="listitem"></div>
<div role="listitem"></div>
</div>
<!-- 😩 Bad: listitem を所有していない -->
<div role="list">
</div>
<!-- 😩 Bad: listitem 単体では存在できない -->
<div role="listitem"></div>
ロールを上書きしない
本来の役割と異なるロールで上書きする事は誤りです。
<!-- 😩 Bad: テーブルタグであるという情報が失われる -->
<table role="log"></table>
標準の HTML と同じ挙動にする
ロールの宣言は、役割とともにその要素がどのように振る舞うのかをユーザーに示しています。そのため button
ロールを宣言した要素は HTML の <button>
タグと同じインタラクションを持つ必要があります。
<!-- 😩 Bad: tabindex 指定がなくタブキー移動ができない -->
<div role="button">
<!-- 😩 Bad: クリックに反応するがスペースやエンターキーが考慮されていない -->
<div role="button" onclick="...">
サンプルコード
WAI-ARIA のドキュメントでロールごとのサンプルコードが紹介されています。キーボード操作なども記載されているため、実装する時は参考にしてみましょう。
-
Design Patterns and Widgets | WAI-ARIA 1.2
- ウィジェットごとのデザインパターンを見る事ができます。
-
デザイン・パターンとウィジェット | WAI-ARIA 1.1
- ひとつ前の仕様ですが日本語で記述されているため見やすいかもしれません。
おわりに
この記事では、アクセシビリティ配慮の入り口に立つための基本的な情報や、個人的な考察について紹介させていただきました。最後に私が「アクセシビリティ配慮されている!」と特に感じたサイトを紹介して終わりにしたいと思います。
参考サイト
-
accessibe
- 何らかの障害を持つ人向けのとてもリッチなアクセシビリティ配慮がなされています。ページ右下にあるアクセシビリティアイコンのボタンをクリックすると、目的に合わせてコンテンツ表示を切り替えできます。
Seizure Safe Profile
をオンにするとてんかん発作のある人に配慮した色合いに変わり、ADHD Friendly Profile
をオンにすると一部だけにスポットライトを当てたような表示に切り替わります。
- 何らかの障害を持つ人向けのとてもリッチなアクセシビリティ配慮がなされています。ページ右下にあるアクセシビリティアイコンのボタンをクリックすると、目的に合わせてコンテンツ表示を切り替えできます。
-
Google Web Fundamental
- キーボード操作によるフォーカス設定が視覚的にも配慮されていてきれいです。
-
ics.media
- macOS の設定の「視覚効果を減らす」に応じてヘッダ画像やボタンのフォーカスのモーションが変わります。タブキー移動のサクサク動く感じがとても気持ち良いです。
-
GitHub
- ボタンやテキストエリアなどインタラクティブな要素が多いため、やや複雑なWeb アプリを実装する際の一番身近なお手本となるのではないでしょうか。WAI-ARIA が細かに設定されています。
Chrome エクステンション
上記のようなサイトは Chrome エクステンションなどを使って、どのようなアクセシビリティ配慮をしているのか探ってみるとなかなか興味深いです。
-
WAVE
- アクセシビリティに関するレポートをビジュアライズ表示します。
-
Visual ARIA
- WAI-ARIA が使われている箇所をビジュアライズ表示します。
-
Landmarks
- WAI-ARIA のランドマークロールをビジュアライズ表示します。