【アクセシビリティ】aria-controlsについて

どうも、くまだです。

WAI-ARIAのaria-controlsについてのメモ。

aria-controlsとは

aria-controlsは「このボタンは、あの要素を操作するよ」と支援技術に伝えるための属性です。

値には、操作される要素のIDを指定します。

<button aria-controls="menu">メニューを開く</button>
<nav id="menu">...</nav>

視覚的には「このボタンを押したらメニューが開く」というのは見ればわかります。

でも、スクリーンリーダーを使っている人にとっては、ボタンとメニューが「関係している」ことが伝わりません。HTMLの構造上、ただのボタンとただのnav要素が並んでいるだけだからです。

これだと何が困るかというと、ボタンを押しても「何が起きたのか」「どこを見ればいいのか」がわからないんですよね。メニューが開いたことも、そのメニューがどこにあるのかも伝わらない。

aria-controlsを使うことで「このボタンは#menuを操作する」という関係性を明示できます。

ハンバーガーメニューで実装すると(CSSは省略)以下のようになります。

<button 
  type="button"
  aria-controls="global-nav"
  aria-expanded="false"
  aria-label="メニュー"
>
  <span></span>
  <span></span>
  <span></span>
</button>

<nav id="global-nav" aria-hidden="true">
  <ul>
    <li><a href="/">ホーム</a></li>
    <li><a href="/about/">会社概要</a></li>
    <li><a href="/contact/">お問い合わせ</a></li>
  </ul>
</nav>

  • aria-controls="global-nav":このボタンが#global-navを操作することを伝える
  • aria-expanded="false":現在メニューが閉じていることを伝える
  • aria-label="メニュー":ボタンの役割を伝える(中身がspanだけなので)

メニューを開いたときは、JavaScriptでaria-expanded="true"aria-hidden="false"に切り替えます。

const button = document.querySelector('button');
const nav = document.querySelector('#global-nav');

button.addEventListener('click', () => {
  const isExpanded = button.getAttribute('aria-expanded') === 'true';
  
  button.setAttribute('aria-expanded', !isExpanded);
  nav.setAttribute('aria-hidden', isExpanded);
});

aria-controlsは「どの要素を操作するか」を伝えるだけで、「今開いているのか閉じているのか」は伝えられません。

開閉状態を伝えるには、aria-expandedを併用します。

  • aria-expanded="false":閉じている
  • aria-expanded="true":開いている

ここまで読んでくださりありがとうございました。

この記事を書いた人