ゼロから始めるWEBアクセシビリティ改善【Part1】

INDEX

気づけば入社して半年が経過していました。ナガノマです!

今回はフロントエンドエンジニアがおさえておきたい、WEBアクセシビリティ改善に関する入門的な内容を取り上げていきます。

Part1(基本編)とPart2(実践編)の2回に分けてご紹介していきますので、ぜひ最後までご覧いただき、アクセシビリティ改善への一歩を踏み出してみてください...!


1.WEBアクセシビリティ改善に取り組む理由

アクセシビリティとは「利用可能な状況の幅広さ」を指します。

つまり、WEB上のサービスを、利用者の環境や心身の条件などになるべく左右されることなく利用可能にすることが、WEBアクセシビリティ改善に取り組むということになります。

代表的な例として、「スクリーンリーダー(※)などの音声読み上げに対応させる」という取り組みはご存知の方も多いかと思います。

※主なスクリーンリーダー
Googleアシスタント
VoiceOver(macOS、iOS標準)

ただ、私自身の感覚として、実装上の負担や成果が見えづらいなどの理由からか、取り組み自体が広く普及していない印象を受けています。

そんな中で、今のうちに取り組んでおくべきである大きな理由があります。それは障害者差別解消法が改正されることによる影響です。


<障害者差別解消法の改正(新旧対照文より抜粋)>


「合理的な配慮」とは
障害のある人から「社会の中にあるバリア(障壁)を取り除くために何らかの対応が必要」との意思が伝えられたときに、行政機関等や事業者が、負担が重すぎない範囲で必要かつ合理的な対応を行うこと


「環境の整備とは」
(合理的な配慮に基づき)不特定多数の障害者を主な対象として行われる事前的改善措置

「合理的な配慮」の提供については、従来は公的機関のみが義務化とされていましたが、2024年の4月以降(遅くとも2024年の6月以降)には、事業者も義務化の対象となることが決定しています。

WEBアクセシビリティが義務化されたわけではありませんが、クライアントやユーザーからアクセシビリティ面での改善要望を受けた場合に、対応する術を知っておく必要性が高まってきています。


2.アクセシビリティ用のDOM

フロントエンドエンジニアがWEBアクセシビリティを学ぶ上で、まず必ずおさえておくべきなのが、通常のDOMとは別にアクセシビリティ用のDOMが存在するということです。

これをアクセシビリティオブジェクトモデル(AOM)、またはアクセシビリティツリーと呼びます。(※以降の説明では、「アクセシビリティツリー」で表記を統一します)

スクリーンリーダーなどの支援技術は、このアクセシビリティツリーをもとにコンテンツ情報をユーザーに伝えることになります。

つまり、アクセシビリティ改善に取り組む上では、このアクセシビリティツリーにコンテンツが正しい形で登録されているかが重要となります。


ちなみにアクセシビリティツリーは、Chromeなどの検証ツール上から確認することができます。

また、アクセシビリティツリー上では、各HTMLタグが4つの構成要素namedescriptionrolestate)を含んでいます。

以下はアクセシビリティツリー上での表示例です(※Chrome117 検証ツール上での結果)

<!--------------------------------------------------------------------
  1.name: 要素の名前
-------------------------------------------------------------------->
<p>テキスト</p> <!-- name: テキスト -->
<img src="thumb.jpg" alt="コードで遊ぼう"> <!-- name: コードで遊ぼう -->

<!--------------------------------------------------------------------
  2.description: 要素の説明
-------------------------------------------------------------------->
<a href="/" title="EVOLAB公式サイト">EVOLAB</a> <!-- description:EVOLAB公式サイト -->

<!--------------------------------------------------------------------
  3.role: 要素の役割
-------------------------------------------------------------------->
<p>テキスト</p> <!-- role: paragraph -->

<!--------------------------------------------------------------------
  4.state: 要素の状態
-------------------------------------------------------------------->
<button type="button" aria-expanded="false"></button> <!-- 展開可能: false -->

これらの情報は、HTMLタグが元々持つ意味や、タグに囲まれたテキストなどを受けてアクセシビリティツリー上に登録されますが、WAI-ARIAを使用することでも登録することができます。


3.WAI-ARIAとは

3-1. 概要

WAI-ARIAとは、先ほど述べた「環境の整備(事前的改善措置)」を行うための一つの手法です。

MDNでは、以下のように説明されています。

W3C によって定められた仕様で、要素に適用できる追加の意味論を提供する一連の HTML 属性を定義しており、それが欠けているどのような場所でもアクセシビリティを向上させます。

簡単にいうと、HTMLに意味づけを行うために使用するHTML属性のことです。

WAI-ARIAという言葉は知らなくても、aria-hidden属性などは見たことがある方も多いかもしれません。これがWAI-ARIAに該当するHTML属性です。

HTMLに正しく意味付けを行うことで、スクリーンリーダーなどの支援技術を用いてWEBサイトを閲覧する場合でも、コンテンツが正しく伝わるようになります。


ただ、HTMLにはリスト要素(<ol>、<ul>)やリンク要素(<a>)といったように、役割ごとに色々なタグが存在しています。

こういったタグは、デフォルトで意味づけされています。つまり、WAI-ARIAを使わずとも、正しくマークアップを行うだけでアクセシブルになるケースも多く存在します。

よって、WAI-ARIAは既存のHTMLタグでは補えないケースにおいて使用すると捉えておくと良いかもしれません。使用例については、本記事の【Part2】のほうで詳しくご紹介します。


3-2. WAI-ARIAの構成要素

先ほど、アクセシビリティツリー上には各HTMLタグが4つの構成要素(namedescriptionrolestate)を含んでいることについて触れました。WAI-ARIAを使用することで、これらの構成要素に情報を渡すことができます。

WAI-ARIAに基づくHTML属性は、主に3つの要素(rolepropertystate)に分類されており、分類に応じてアクセシビリティツリーに渡す情報が異なります。

以下は具体例です(※Chrome117 検証ツール上での結果)

<!--------------------------------------------------------------------
  1.role(ロール): HTML要素の意味を定義
-------------------------------------------------------------------->
<div role="list"></div> <!-- アクセシビリティツリー上の「role(役割)」を"list"に設定  -->

<!--------------------------------------------------------------------
  2.property(プロパティ): HTML要素の性質を定義(=静的な情報)
-------------------------------------------------------------------->
<button type="button" aria-label="メニューを開く"></button> <!-- アクセシビリティツリー上の「name」に情報を追加 -->
<a href="/" aria-description="EVOLAB公式サイト"></a> <!-- アクセシビリティツリー上の「description」に情報を追加 -->

<!--------------------------------------------------------------------
  3.state(ステート): HTML要素の現在の状態を定義(=動的な情報)
-------------------------------------------------------------------->
<div aria-hidden="false"></div> <!-- アクセシビリティツリー上で表示/除外する -->
<button type="button" aria-selected="true"></button> <!-- 要素が選択されている/選択されていない -->

注意点として、これらのHTML属性はどのようなケースでも使用して良いというわけではなく、HTMLタグの種類やrole属性などに依存して使用できない属性もあったりと、使用可能かどうかの一定のルール(WAI-ARIAARIA in HTMLCore Accessibility API Mapping (Core-AAM))が存在しています。


3-3. 意味づけが競合した場合

HTMLタグにはデフォルトで意味付けされているものが多数存在します。では、既に意味を持っているHTMLタグに対してWAI-ARIAでも意味づけを行った場合はどうなるのでしょうか。

また、同じようなケースとして、アクセシビリティツリー上から除外するWAI-ARIA属性としてaria-hidden="true"がありますが、実はCSS上でdisplay:none;を指定することでもアクセシビリティツリー上から除外することができます。

このように意味づけが競合した場合、基本的には以下の優先順で処理されます。

HTMLタグが元々持つ意味 < CSS < WAI-ARIA

ただ、一般的にこのケースに当てはまることが多いというだけで、ブラウザ(またはバージョン)によっては優先順位が入れ替わるケースも存在します。また、ルール上、そもそもWAI-ARIAが使用できないというケースもあるため、あくまで参考程度に捉えていただければと思います。

以下は具体例です(※Chrome117 検証ツール上での結果)

<!-- ①HTMLタグが元々持つroleが表示される→ 結果:role="navigation" -->
<nav>ナビ</nav>

<!-- ②WAI-ARIAで上書きされる → 結果:role="list"  -->
<nav role="list">ナビ</nav>

<!-- ③結果:アクセシビリティツリー上に表示 -->
<nav aria-hidden="false">ナビ</nav>

<!-- ④CSSで上書き → 結果:アクセシビリティツリー上から除外 -->
<nav aria-hidden="false">ナビ</nav>
<style>
  nav {
    display: none;
  }
</style>

<!-- ⑤結果:アクセシビリティツリー上から除外 -->
<nav aria-hidden="true">ナビ</nav>
<style>
  nav {
    display: block;
    visibility: visible;
  }
</style>

基本的には競合させないことがベストですが、デザインやアニメーションの実装上、使わざるを得ないということもあるため、その際はアクセシビリティツリー上での表示がどうなっているかを都度確認しておく必要があります。


4. インタラクティブ要素

WAI-ARIAとは別の切り口になりますが、HTML Living Standardで定義されているインタラクティブコンテンツ<a><button>など)も、アクセシビリティ面では重要な要素です。

これらのタグは、キーボード(矢印キー、tabキーなど)でのフォーカス移動、クリック(選択)、スクリーンリーダーでの読み上げ(通知)に対応しています。

逆に言えばこれらのタグを使用せずに実装した場合、キーボード、およびスクリーンリーダー等の支援技術を使用した際に操作できないという状況を生み出してしまいます。

解決策としては、インタラクティブコンテンツに該当するHTMLタグに置き換えるか、WAI-ARIAを使用してインタラクティブコンテンツとしての意味づけを行います。

代表的な例だと、tabIndex属性などはフォーカス可能かどうかを制御することができます。本記事の【Part2】のほうで詳しくご紹介しますが、詳細が気になる方はMDNをご確認ください。


5. おわりに

WEBアクセシビリティ改善の基本についてご紹介しました。

今回は私自身がゼロから学んでみて、重要だと感じた部分をピックアップしてご紹介しましたが、まだまだ奥が深い分野なので、継続的にキャッチアップしていかなければなりません。


Part2の実践編では、デモを用いてアンチパターンをどう改善していくかをご紹介する予定なので、そちらもぜひ読んでみてください。

ご拝読ありがとうございました!


参考


PREV

BLOG一覧

NEXT

最新記事 Latest