どうも、くまだです。
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":開いている
ここまで読んでくださりありがとうございました。