masuP.net

aria-expandedのよくある間違い

WAI-ARIAの中で、コンテンツが展開されているかどうかの状態を表すaria-expandedは、WAI-ARIAの中でもよく使われている属性のうちの一つ[注1]ですが、誤った使い方をみかけることも少なくありません。また私自身も間違った理解のまま使用していた時期もありました。

[注1] : 出典 Usage of ARIA attributes - Analysis - Discuss - HTTP Archive

そこでaria-expandedのよく見かける間違いと、仕様に基づいた正しい使い方をまとめました。

間違いその1:aria-hiddenaria-expandedを混同する

aria-expanded要素、または要素が制御する別のグループ化要素が、現在展開されるまたは折りたたまれるかどうかを示す。ステートです。要素そのものが隠れているかどうかを示すaria-hiddenとは異なります。

例えばアコーディオンUIのマークアップの場合、aria-expandedは、折りたたまれて非表示になるアコーディオンパネルの要素に付与するのではなく、その親要素か、展開を制御する要素に付与するべきです。

よくある間違い
<button type="button" aria-controls="section1">開く</button>
<section id="section1" aria-expanded="false" >
  コンテンツ
</section>
正しい使用例 - 展開を制御する要素に付与する例
<button type="button" aria-expanded="false" aria-controls="section1">開く</button>
<section id="section1" aria-hidden="true">
  コンテンツ
</section>
正しい使用例 - アコーディオンパネルの親要素に付与する例
<div aria-expanded="false">
  <button type="button">開く</button>
  <section id="section1" aria-hidden="true">
    コンテンツ
  </section>
</div>

間違い:展開する要素を所有していない場合に制御するコンテンツを明示していない

間違いその1の正しい使用例として提示した「展開を制御する要素に付与する例」のように、aria-expandedが付与された要素が展開されうる要素を所有していない場合は、制御するコンテンツを明示する必要があります。

aria-expanded属性をもつ要素が要素'によって所有'されない別のグループ化コンテナの展開を制御する場合、著者はaria-controls属性を使用することによってコンテナを参照すべきである

https://momdo.github.io/wai-aria-1.1/#aria-expanded

この場合の所有しているという状態は仕様の中の重要な用語でも定義されていますが、次のいずれかです。

  • DOM子孫として持つ
  • aria-ownsで指定する
  • aria-ownsで指定した要素の子孫要素

特別な理由が無く素直にマークアップできるのであればDOM子孫として持てますが、複雑なレイヤーが重なり合う動画プレイヤー上のメニューや画面のスクロール位置によって展開位置を変更するようなメニューについては、DOM的に離れた箇所に展開されうる要素を置くケースがあります。

YouTubeの動画プレイヤー上の設定メニュー

そのような場合はaria-controlsで展開を制御する要素を明示する、もしくは展開されうるコンテンツを所有する必要があります。

所有している例
<ul aria-expanded="true" role="tree">
<li role="treeitem">展開されるコンテンツ</li>
<li role="treeitem">展開されるコンテンツ</li>
<li role="treeitem">展開されるコンテンツ</li>
</ul>
aria-ownsで所有する例
<button type="button" aria-expanded="true" aria-owns="tab1">ボタン</button>
<!-- 〜〜〜 -->
<div id="tab1">
展開されるコンテンツ
</div>
aria-controlsで明示する例
<button type="button" aria-expanded="true" aria-controls="tab1">ボタン</button>
<div id="tab1">
展開されるコンテンツ
</div>
明示できていない例
<a href="#tab1" aria-expanded="true">ボタン</a>
<div id="tab1">
展開されるコンテンツ
</div>

aria-ownsaria-controlsのどちらを使うかどうかは、特別な制約がない場合においてDOM構造的に所有する形でも違和感がないかどうか、から考えるのが自然なように思います。この際は要素のコンテンツモデルに関して気にする必要はないように思います。例えば<button>の中にXXは置けないなど

または、aria-ownsで参照される要素は、他の要素のaria-ownsから参照されないことを保証しないといけないので、複数のトリガーから展開をコントロールされることが考えられる場合はaria-controlsが適していると考えられるでしょう。


コンテンツの展開は、インタラクティブなユーザーインターフェースとしては頻出かつ基本的なものになりますので、きちんと仕様を読み理解して抑えたいですね。