見出し画像

#50 アクセシブルなアコーディオンを作る【ぴよぴよコーダーの開発日記】

まずはデモ。その前にアクセシブルとは何ぞや、と言うことですが、平たく言うと、あらゆる人がアクセスしやすいって意味で大丈夫かと思います。

アクセシブルなアコーディオンのデモ

アクセシブルじゃないアコーディオンのデモ

違いがわかるだろうか。アクセシブルなデモはタブキーが動くんですね。

だから何だって感じかもしれませんが、WebアクセシビリティのガイドラインであるWCAG2.0で、こんなルールがあるそうです。

コンテンツのすべての機能は、個々のキーストロークに特定のタイミングを要することなく、キーボードインタフェースを通じて操作可能である。

出典元:WCAG2.0解説書 キーボード操作可能

ちなみに、WCAGとは、Web Content Accessibility Guidelinesの略。あらゆる人がUIにアクセスできると言うやさしい世界線のルール。

参考:アクセシブルなアコーディオンパネルにするために考えなければならないこと

↑の参考サイトはaタグでの事例がありましたが、今回はbuttonタグで実装しました。aタグといってもhrefで遷移する場所はないので。タブ操作であればbutton要素で大丈夫かなと。コードは下記

<dl id="acMenu">
       <dt><button type="button" role="tab" aria-controls="accordion1" aria-selected="false" aria-expanded="false">Step.1 <span class="icon--toggle" title="メニューを開く">+</span></button></dt>
       <dd role="tabpanel" id="accordion1" aria-hidden="true">Step.1の内容</dd>
</dl>

ちなみにアクセシブルじゃないほうのコードはこちら

<dl id="acMenu">
       <dt>Step.1 <span class="icon--toggle">+</span></dt>
       <dd>Step.1の内容</dd>
</dl>

上のほうのコードは下に比べて、なんかbutton要素以外にも、roleやらaria-controlsやら、いっぱい書かれている。これは何ぞや。ってことをこれから調べてみます。

role属性とaria属性とは?

role属性:コンテンツの役割。roleって日本語で役だね。

aria属性:コンテンツの状態や性質。ちなみにariaとは、Accessible Rich Internet Applicationsの略だそうです。アクセシブルなリッチなアプリ。

さて、role属性。このアコーディオンではトリガーとなるbuttonに、role="tab" という役割をつけている。アコーディオンだけど後続に開くコンテンツがあるからタブと同じ

そして、後続の開くコンテンツには、role="tabpanel" という役割づけ。そのまんまの意味ですね。

次に、aria属性。ずらずらいっぱい書かれています。と言っても4つくらいなので、一つ一つ説明します。

aria-controls属性:平たく言うと、labelタグにあるfor属性とinputタグのidのような関連付けができる属性。このソースでは、aria-controls="accordion1"とbuttonに付与して、開くコンテンツのほうに、id="accordion1"と同じ名前を付けて関連付けをしている。

aria-selected属性:これもselectedと同じような機能。選択されてないときは値にfalseが入り、選択されてたらtrueが入る

aria-expanded属性:要素の開閉の状態を示すためのWAI-ARIAの属性。まさにタブやアコーディオンのためにある属性ですね。expandは日本語で広がるだから、過去形でexpanded、広がった状態か。初期状態は広がってないから、aria-expanded="false"ということ。これはトリガーのbuttonのほうにつける属性。

aria-hidden属性:これもそのまま表示されていないかという状態を表す。非表示の要素があったら、隠れてますよということで、aria-hidden="true"。

状態を示すaria属性は、jQueryで開いてる状態と閉じてる状態の書き換えをします。コードは下記。

$(function(){
   $("#acMenu > dt > button").on("click", function() {
           $(this).parent('dt').next().slideToggle();
           if($(this).find('.icon--toggle').text() === '+'){
               $(this).find('.icon--toggle').text('―');
               $(this).find('.icon--toggle').attr('title', 'メニューを閉じる');
               $(this).attr('aria-selected', true);
               $(this).attr('aria-expanded', true);
               $(this).parent('dt').next('dd').attr('aria-hidden', false);
           } else {
               $(this).find('.icon--toggle').text('+');
               $(this).find('.icon--toggle').attr('title', 'メニューを開く');
               $(this).attr('aria-selected', false);
               $(this).attr('aria-expanded', false);
               $(this).parent('dt').next('dd').attr('aria-hidden', true);
           }
       });
   });

このif文の分岐なんなんって気もしますが、buttonをクリックしたときにアイコンが+の時は、アイコンを-に変更して、title属性にメニューを閉じるという補助文言を変更する。そしてそれぞれのaria属性の値をセットする。開いてる状態だから、aria-expandedはtrueで、選択されてるから、aria-selectedもtrueで、コンテンツは表示されているから、aria-hiddenはfalseである、閉じているときはその反対の処理。

参考:aria属性を使ってタブを実装してみた

参考:アクセシビリティを意識したWAI-ARIA実装について

参考:WAI-ARIAを使用したJSアコーディオンの実装

参考:aria-expanded属性

参考:ReactとWAI-ARIAでアクセシブルなアコーディオンUIを実装してみた

参考:【jQuery】アコーディオン実装サンプル10選

ちなみに、上記のJSのソースにtitle属性で、メニューを開く、メニューを閉じる と、書き換えてますが、これも+というアイコンだけでは、何を意味するかわからないので、title属性で情報を補足しています。スクリーンリーダーもtitle属性を読みますが、文字列としてブラウザに表示させたいときは、imgタグでアイコンを作って、altで書き換えてもよいかもしれません。aria-label属性で明記するのもいいって、デモ作った後に気づきました。

参考:【アクセシビリティ】HTML/CSSで突っ込まれた点をメモメモ

参考:fontawesome   ここのハンバーガーメニューはtitle属性だった

参考:知っていると便利なaria-label属性の使い方

参考:代替テキストはtitle属性で代用可能か

後日やる予定:aria-label属性とaria-labelledby属性を書き忘れていたので追加するかも。

この記事が気に入ったらサポートをしてみませんか?