ハンバーガーメニューのアクセシブル

①ボタンとメニューの関係性を設定

「このボタンを押したら、このメニューが開く/閉じる」というような、ある要素から別の要素の表示を制御する関係性を表現するのがaria-controls属性である。制御される側にid属性で固有名を付けておき、制御する方にaria-controls属性でそのid属性を指定するようにする。

<button type="button" class="hamburger" aria-controls="gnav">
 <span class="hamburger__line"></span>
 <span class="hamburger__txt">Menu</span>
</button>
<nav id="gnav" class="gnav">
 <ul class="gnav__list">~省略~</ul>
</nav>

②開閉状態を設定

現在のハンバーガーメニューの開閉状態をステートで設定する。
ボタン側には aria-expanded(制御先の要素が展開されているかどうか)。
メニュー側には aria-hidden(自分自身が非表示であるかどうか)。
を設定するようにする。メニューが開いている状態/閉じている状態を表現する場合の値は以下の通り。

  • aria-expanded(ボタン側):メニューが閉じている時「false」/メニューが開いている時「true」
  • aria-hidden(メニュー側):メニューが閉じている時「true」/メニューが開いている時「false」
<button type="button" class="hamburger" aria-controls="gnav" aria-expanded="false">
 <span class="hamburger__line"></span>
 <span class="hamburger__txt">Menu</span>
</button>
<nav id="gnav" class="gnav" aria-hidden="true">
 <ul class="gnav__list">~省略~</ul>
</nav>

③CSSとJSにステートを反映

aria-expandedとaria-hiddenはいずれもステート(状態)であり、ユーザの操作によってリアルタイムにその状態は変化する。したがって、HTMLに記述した初期状態から変化があった場合には当然aria-属性の値も動的に変更する必要がある。 なおaria-属性はCSSからもJSからもセレクタとして利用可能なので、WAI-ARIAを使っているのであれば状態変化に関する制御についてはaria-*属性を直接セレクタとして利用するのが合理的である。

/* OPEN時スタイル */
.hamburger[aria-expanded="true"] .hamburger__line { background: transparent; }
.hamburger[aria-expanded="true"] .hamburger__line::before { top: 0; transform: rotate(45deg); }
.hamburger[aria-expanded="true"] .hamburger__line::after { bottom: 0; transform: rotate(-45deg); }
<script>
 $(function(){
  $('.hamburger').on('click',function(){

   const expanded = $(this).attr('aria-expanded');  //開閉状態を格納
   const $btnTxt = $('.hamburger__txt');
         const $gnav = $('#gnav');

   if(expanded === 'false'){  //メニュー非展開だったら
    $(this).attr('aria-expanded',true);
    $btnTxt.text('Close');
    $gnav.attr('aria-hidden',false).slideDown();

   }else {  //メニュー展開済みだったら
    $(this).attr('aria-expanded',false);
    $btnTxt.text('Menu');
    $gnav.attr('aria-hidden',true).slideUp()
   }
  });
 });
</script>
inserted by FC2 system