アクセシビリティツリーを読んでアクセシブルな実装に役立てよう

## はじめに

この記事は、[アクセシビリティ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/accessibility)の参加記事です。

## アクセシビリティツリーとは

アクセシビリティツリーは別名アクセシビリティオブジェクトモデルとも呼ばれ、DOMツリーに基づいて生成されるスクリーンリーダーなどの支援技術に使用される情報です。

つまり、アクセシビリティツリーを確認することで、どのような情報が支援技術に提供されているかがわかり、アクセシビリティ対応に役立ちます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGKKoRY" data-user="kabechiyo13" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kabechiyo13/pen/bGKKoRY">
  Untitled</a> by かべちよ (<a href="https://codepen.io/kabechiyo13">@kabechiyo13</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

例えば、アイコンにMaterial Symbolsを使用したこのボタンをアクセシビリティツリーで見てみると以下のように表示されます。

![button "送信する send" focusable: true StaticText="送信する" StaticText="send"](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/49211fc7-b1ae-3939-e977-cbd1df24caca.png)

ボタンのラベルとして表示している「送信する」のテキストだけでなく、Material Symbolsはアイコンフォントのため、アイコンを表示するために指定したテキストの「send」もボタンのテキストとして渡されており、「送信する send」という冗長なラベルがボタンについてしまっています。

これは要素をアクセシビリティツリーに渡さないようにする`aria-hidden: true;`をアイコンに指定すると、アイコンに指定したテキストが無視されるようになり、防ぐことができます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="RwJJLjo" data-user="kabechiyo13" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kabechiyo13/pen/RwJJLjo">
  Button for Accessibility tree 2</a> by かべちよ (<a href="https://codepen.io/kabechiyo13">@kabechiyo13</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

アクセシビリティツリー上で無事、ボタンのラベルが「送信する」になっていることを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/97724b8e-70c3-65be-5279-d00993468df1.png)

このようにアクセシビリティツリーを確認することで、レンダリングされたページや通常のDOMツリーを見ているだけでは気付きづらいアクセシビリティ上の欠陥に気づくことができます。

## アクセシビリティツリーの表示方法（Chrome）

Chromeでは検証モードのAccessibilityのタブ`Enable full-page accessibility tree`にチェックを入れ画面上部に出てくる`Reload DevTools`をクリックすると、右上にアクセシビリティアイコンが出てアクセシビリティツリーを確認することができます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/fb96fa2b-7e7d-0c01-5ee3-164252fe7469.png)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577501/32c8caed-d962-4119-d5de-290c7377e477.png)

## アクセシビリティツリーの読み方

アクセシビリティツリーには`role`、`name`、`description`,`state`などを持っていて、それぞれ以下のような情報を読み取ることができます。

- `role（役割）`
    - 要素の種類を示す
    - タグやrole属性によって割り振られる
    - Ex) ボタン要素には`button`、テキスト要素には`staticText`　など
- `name（名前）`
    - 要素の情報を提供するテキスト
    -  `aria-labelledby`、`aria-label`、`label`、`placeholder`、`figcaption`、`alt`、`caption`、`legend`、`text contents`、`title`、`value`などから生成される
    - Ex) 「　送信する」というボタンには`送信する`など
- `description`
    - 要素に関する追加の説明を提供するテキスト
    - `aria-describedby`、`title`、`placeholder`などから生成される
    - Ex) メールアドレスを入力するテキストボックスのプレースホルダーの`exampla@mail.com`など
- `state`
    - 要素の状態を示す
    - Ex) 折りたたみ要素が折りたたまれているなら`expanded: true`、フォーカス可能な要素なら`focusable: true`など

これらの情報を参照することで、マークアップが意図した通りにアクセシビリティツリーに反映されているのか、もしくはいないのかを確認することができます。

また、アクセシビリティツリー上で`Ignored`と表示されたノードは無視され、支援技術上で読み上げられません。
例えば、`aria-hidden: true`が指定されたアイコン要素などは`Ignored`と表示され、無視されます。

これを確認することで、冒頭で紹介したような装飾のための要素で読み上げられると情報の理解に邪魔になる要素（アイコンなど）を支援技術でスキップさせたいときにきちんとスキップされているかを確認することができます。

## 参照記事

MDNのAccessibility treeに関するページです。
日本語で書かれていて読みやすいのでざっとアクセシビリティツリーについて知るのにおすすめです。

https://developer.mozilla.org/ja/docs/Glossary/Accessibility_tree

W3Cの`name`と`description`に関するページです。
英語ですが、`name`と`description`を決定する方法について解説されていて、関連する用語も多く紹介されています。

https://www.w3.org/TR/accname-1.1/

Chrome Developers のChromeのアクセシビリティツリーに関するブログです。
Chromeのアクセシビリティツリーの概要が紹介されています。

https://developer.chrome.com/blog/full-accessibility-tree/

Chromium Code SearchのAccessibilityに関するページです。
アクセシビリティとアクセシビリティツリーの概要について紹介されています。

https://source.chromium.org/chromium/chromium/src/+/main:docs/accessibility/overview.md

Level Accessの`name`と`description`を決定する方法についての記事とARIAツリーについての記事です。

https://www.levelaccess.com/how-the-w3c-text-alternative-computation-works/

https://www.levelaccess.com/creating-an-accessible-aria-tree-control/