【アクセシビリティ】WAI-ARIAを完全に理解した。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/1f73fdb5-68a0-99f8-2e64-d7d46a63e9ed.png)
## はじめに
みなさんは、WAI-ARIAを知っていますか？


私は、スクリーンリーダーでも読めるようにするため、`aria-label` を使ったり、
`role`を使って、要素の役割を明確にしたりなど業務でよく使うものは、理解しているつもりです。

ただ他にどんな種類のWAI-ARIAがあるか、その役割はなんなのか、
いまいちわからないなと思っていませんでした。

なので今回は、調べたWAI-ARIAについて、まとめたので、ぜひご覧ください。

私の理解度は↓この位置です。 ご注意ください。

:::note warn
1.完全に理解した　← 今ここ
2.なにもわからない
3.チョットデキル
:::

## WAI-ARIA
### WAI-ARIAとは？
WAI-ARIAは、**Web Accessibility Initiative Accessible Rich Internet Applications**の略で、アクセシビリティ向上の目的で、W3Cが定めた仕様です。

また、WAI-ARIAをつかうことで、HTMLで表現できない意味(セマンティック)を属性で補完することができ、
スクリーンリーダーなどの支援技術を通じて、障害を持つ方に対しても適切な情報を伝えられるようになります。

WAI-ARIAにはコンテンツの役割を示す**role属性**とコンテンツの状態や性質を示す**aria属性**が定義されて、role属性やaria属性を使いこなすことで、意味ない `<div>` なのでネストされた複雑なUIの意味(セマンティック)を補完して、アクセシビリティを向上させることができます。

### WAI-ARIAの使うタイミング
これまでは、WAI-ARIAの概要について解説していましたが、
WAI-ARIAはいつ使えばいいのでしょうか？

実は、WAI-ARIAを有効的に使う4つの場面があります。

#### 1. 道しるべ　・　ランドマーク
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/3e09df67-04d5-5229-c2be-9479015802ba.png)
WAI-ARIAの `role属性` には、HTML要素の意味論を再現するように振る舞ったり、
HTML要素で表現できないような要素に `search`・`banner`・`tab` といった役割を示すことが出します。

```sample.html
<nav> <!--ナビゲーション--> </nav>
<div role="navigation"> <!--ナビゲーション--> </div>
```
*これら2つは同じナビゲーションという役割をしてしている。*
　
　
#### 2. 動的なコンテンツの更新
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/b720f108-dd4b-7d5d-b40f-9549c6ce5c20.png)
スクリーンリーダーなどは、絶えず更新されるコンテンツが得意ではない傾向があります。
そのため、スクリーンリーダーのユーザーに対して、動的なコンテンツの更新を伝えるため、 `aria属性` の `aria-live` を使えば、それらを伝えることができます。

```sample.html
<progress value="53" max="100" aria-live="polite">進歩率:53%</progress>
```
*上記の例では、100%になったタイミングでユーザーに伝えることができます。*
　
　
#### 3. キーボードのアクセシビリティの向上
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/4c8a3ad6-0220-15fe-42b1-47ed04ae730e.png)
キーボードのアクセシビリティを最初から持つHTML要素がありますが、JavaScriptを使って、それ以外の要素に同じようなインタラクションをさせる場合、スクリーンリーダーにとって困難が生じます。

そのため、`tabindex` を使うことで、他の要素に対してフォーカスさせることができます。

```sample.html
<div tabindex="1">ボタン</div>
```
*上記の例では、tabキーで `<div>` にフォーカスが当たるようになります。*
　
　

#### 4. 意味論的ではないコントロールのアクセシビリティ
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/3fbc7386-7c01-8c5b-25a3-373c06894009.png)
CSSやJavaScriptによって複雑なUIで構成していたり、JavaScriptによってネイティブのコントロールが大きく強化/変更されていると、アクセシビリティの提供は困難になり、特にスクリーンリーダーのユーザーはその機能が何をするのか判断するのが難しくなります。

そのため、このような状況では、 `button`・`listbox`・`tabgroup` といったロールを組み合わせたり、
`aria-required`・`aria-posinset` などのプロパティで、機能の手がかりを提供することで、足りないものをWAI-ARIAで補うことができます。

```sample.html
<h2 id="periodictable">化学元素の周期表</h2>
<ul role="listbox" aria-labelledby="periodictable">
  <li role="option" aria-setsize="118" aria-posinset="1">水素</li>
  <li role="option" aria-setsize="118" aria-posinset="3">リチウム</li>
  <li role="option" aria-setsize="118" aria-posinset="11">ナトリウム</li>
  <li role="option" aria-setsize="118" aria-posinset="19">カリウム</li>
</ul>
```
*上記の例では、118の化学元素の周期表の中で`<li>`が何番目に位置しているかをサポートしています。*
　
　

### WAI-ARIAの使用上の注意
アクセシビリティを意識するあまり、*role属性*や*aria属性*をむやみやたらに使うのはよくありません。
**WAI-ARIAは必要な場合のみ使用する** ということは、覚えておきましょう。

その他にも、WAI-ARIAを使う上で注意しないといけないことがあるので紹介します。

#### 1. できるだけHTML要素の意味を使う。
ネイティブのHTML要素や属性に必要とする意味（セマンティック）があるなら、
**role属性やaria属性を追加せずに**ネイティブのHTML要素や属性を優先的に使ってください。

```sample.html
⭕️ <nav> /*ナビゲーション*/ </nav>
❌ <div role="navigation"> /*ナビゲーション*/ </div>
```
*`<nav>`を使えるなら`role="navigation"`で指定ぜずに`<nav>`を使う。*

　
#### 2. できるだけHTML要素の意味を変えない。
本当に必要な場合を除いて、ネイティブのHTML要素の意味（セマンティック）変えないでください。

```sample.html
⭕️ <div role="tab"> <h2>タブラベル</h2> </div>
❌ <h2 role="tab">タブラベル</h2>
```
*タブに見出しを使いたい時は、`<h2>`をタブにしない*

　
#### 3. インタラクティブなARIAコントロールは、全部キーボードで操作可能にする。
すべてのインタラクティブARIAコントロールは、キーボードで操作可能でなければいけません。

ユーザーが、`クリック`・`タップ`・`ドラック＆ドロップ`・`スクロール` などでウィジェットを作成できる場合には、
キーボードだけで、同等のアクションが実行できないといけません。

例えば、`role=button` を指定する場合、`Enterキー`・`Returnキー`・`Spaceキー`を使って、ボタンのアクションを実行できるようにしないといけません。

　
#### 4. フォーカス可能な要素には、`role="presentation"`と`aria-hidden="true"`を使わない。
フォーカス可能な要素には、`role="presentation"`と`aria-hidden="true"`を使わないでください。

`role="presentation"`は、指定した要素とその子・子孫要素の意味（セマンティック）を取り除きます。
`aria-hidden="true"` は、指定した要素とその子・子孫要素のインタラクティブな要素を非表示にします。

```sample.html
❌ <button role=presentation>押してください</button>
❌ <button aria-hidden="true">押してください</button>
```

　
#### 5. すべてのインタラクティブな要素には、アクセス可能な名前が必要。

すべてのインタラクティブな要素には、アクセス可能な名前が必要です。

`aria-label`で名前をつけたり、`<label>`で名前をつけたりすることができます。

```sample.html
⭕️ <input type="text" aria-label="User Name">
⭕️ <label>User Name<input type="text" role="combobox"></label>
```

　
### アクセシビリティのチェック方法
アクセシビリティのチェックするには、以下のように行うのがおすすめです。
#### 1. キーボードだけでインタラクティブな要素にアクセスすることが可能か？
`タブキー`・`Enterキー`・`Returnキー`・`Spaceキー`・`←キー`・`↓キー`・`↑キー`・`→キー`などでインタラクティブな要素にちゃんとアクセス・フォーカスできるか確認します。

|例：Qiita|
|:--:|
|![スクリーンショット 2022-11-01 3.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/1f03f3dd-6729-b1d3-4ec3-fdce10b53bcf.png)|


　
#### 2. スクリーンリーダーでも情報にアクセスすることが可能か？
F12の検証ツールのアクセシビリティの項目からどのように読まれているか確認することができます。

|例：Qiita|
|:--:|
|![スクリーンショット 2022-11-01 3.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/44014148-716d-a791-ec22-e73e13811c78.png)|




## WAI-ARIAの種類
ここまでは、WAI-ARIAについて解説していきました。
ここからは、WAI-ARIAの「**コンテンツの役割を示すrole属性**」、「**コンテンツの状態と性質を示すaria属性**」 それぞれにどのようなものがあるか解説して行きます。

ぜひストックして、必要なところに必要なものを記載してみてください。

### コンテンツの役割を示すrole属性
コンテンツの役割を示すrole属性は、次のように分類することができ、それぞれ、このような使用されています。

1. **抽象役割**
    - 抽象役割は、一般的な役割概念を定義する目的で使われます。
    - そのため、コンテンツに抽象役割を使用してはいけません。 
    - 例： `command`・`input` etc.
1. **ウィジェット役割**
    - ウィジェット役割は、独立したUIウィジェットや大きな複合ウィジェットで使われます。
    - 例： `button`・`menu` etc.
1. **文書構造役割**
    - 文書構造役割は、インタラクティブな要素ではなく、ページの文章構造を記述するために使われます。
    - 例： `article`・`list` etc.
1. **ランドマーク役割**
    - ランドマーク役割は、ナビゲーションなど、意図されるページの領域を示すために使われます。
    - 例： `banner`・`main` etc.

role属性の各属性についての詳しい解説は、以下のリンクから参照ください。

https://qiita.com/degudegu2510/items/3fde7d188a90d5b94fc1

### コンテンツの状態と性質を示すaria属性
aria属性の状態とプロパティは以下のように分類されます。

1. **ウィジェット属性**
    - 汎用のユーザーインターフェース要素で、ユーザーの入力を受信してユーザーの操作を処理するものに用いられ、それらのウィジェットをサポートします。
    - 例： `aria-hidden`（状態）・`aria-label` etc.
1. **ライブ領域属性**
    - アプリケーション内のライブ領域を対象とする属性に用いられ、コンテンツ更新の処理方法に関する情報をサポートします。
    - 例： `aria-busy`（状態）・`aria-live` etc.
1. **ドラッグアンドドロップ属性**
    - ドラッグアンドドロップインターフェイス要素について、それに関する情報を表す属性に用いられ、視覚的に描き示されたり、代替モダリティでサポートします。
    - 例： `aria-grabbed`（状態）・`aria-dropeffect` etc.
1. **関係属性**
    - 文書構造から容易に決定することができない要素間の関係の情報をサポートします。
    - 例： `aria-labelledby`・`aria-posinset` etc.

aria属性の各属性についての詳しい解説は、以下のリンクから参照ください。

https://qiita.com/degudegu2510/items/3fde7d188a90d5b94fc1

## まとめ
今回は、調べたWAI-ARIAについてまとめ、WAI-ARIAを完全に理解しました。

1つ１つのプロパティを理解するのは簡単でも、
何十個もあれば、手をつけるのも億劫になります。

そのため、この記事が、WAI-ARIAを理解するための第一歩となれると嬉しいです。

ぜひこの記事が参考になった・WAI-ARIAの理解が進んだという方がいれば、
LGTMとストックをお願いします。🙏

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510