①ロールを設定
ul要素で作ったタブリストと、div要素で作った各タブパネルに対して、これが「タブUI」であるということを示すために、role属性を設定していく。タブ一覧はrole=”tablist”、タブはrole=”tab”、タブパネルはrole=”tabpanel”である。
また、button要素にrole=”tab”を当てる場合、li要素がアクセシビリティツリー的には不要となるため、li要素にはrole=”presentation”を割り当てるのがポイントである。
<div class="tabs">
<ul class="tab-list" role="tablist">
<li class="tab-list__item" role="presentation">
<button type="button" id="tab01" class="tab is-active" data-target="tabpanel01" role="tab">タブ1</button>
</li>
~省略~
</ul>
<div id="tabpanel01" class="tab-panel is-active" role="tabpanel">タブパネル1</div>
~省略~
</div>
②タブとパネルの関係性を設定
タブ側からはaria-contorols属性で対応するパネルのidを、パネル側からはaria-labelldeby属性で対応するタブのidを指定しておく。
また、制御対象を指定していたdata-target属性はaria-contorols属性で置き換え可能となるので削除しておく。
<div class="tabs">
<ul class="tab-list" role="tablist">
<li class="tab-list__item" role="presentation">
<button type="button"
id="tab01"
class="tab is-active"
data-target="tabpanel01" <-不要となるので削除
role="tab"
aria-controls="tabpanel01">タブ1</button>
</li>
~省略~
</ul>
<div id="tabpanel01" <-aria-contorolsで指定する制御対象のid
class="tab-panel is-active"
role="tabpanel"
aria-labelledby="tab01">タブパネル1</div>
~省略~
</div>
③タブの選択状態を設定
タブUIは、用意されたタブの1つだけが選択されており、他のタブパネルは隠されている状態になるので、タブUIの初期状態をaria-属性のステートで表現する必要がある。 まずタブ側には aria-expanded(制御先の要素が展開されているかどうか)/aria-selected(自分自身が選択されているかどうか) タブパネル側には aria-hidden(自分自身が非表示であるかどうか)を設定する。
- aria-expanded(タブ側):選択されているタブ(true)/選択されていないタブ(false)
- aria-selected(タブ側):選択されているタブ(true)/選択されていないタブ(false)
- aria-hidden(タブパネル側):選択されているタブ(false)/選択されていないタブ(true)
状態変化のスタイルについてはaria-属性のステートをそのままセレクタとして利用することが可能なので、タブ・タブパネルそれぞれで「現在選択されているもの」を指定していたclass=”is-active”は削除し、CSS側の表示制御もaria-*属性をセレクタとしたものに書き換えている。
.tab[aria-selected="true"] { /* 選択中のタブ。.is-activeの代わりにaria-selectedを使用 */
background: #fff;
border-bottom: 1px solid #fff;
}
.tab-panel[aria-hidden="false"] { /* 選択中のタブパネル。.is-activeの代わりにaria-hiddenを使用 */
display: block;
}
④タブの選択/非選択の挙動をJSで実装
タブをクリックした時に選択されたタブ/タブパネルにclass=”is-active”を付け替える代わりに、aria-属性の値を切り替えるようにしている。各タブ/タブパネルの選択/非選択時のスタイルはaria-属性をセレクタとしてCSSで指定済みなので、これだけでビジュアルブラウザ/スクリーンリーダーの双方に対して選択状態を示すことができる。
あとは表示されたタブパネル側にフォーカスを移動して中身を読みやすくするため、各タブパネルに対してtabindex=”0″を指定しておけば、比較的軽微な対応でタブUIのアクセシビリティ対応が完了する。
<div class="tabs">
<ul class="tab-list" role="tablist">~省略~</ul>
<div id="tabpanel01" ...省略... tabindex="0">タブパネル1</div>
<div id="tabpanel02" ...省略... tabindex="0">タブパネル2</div>
<div id="tabpanel03" ...省略... tabindex="0">タブパネル3</div>
</div>
<script>
$(function(){
$('.tab').on('click',function(){
const $tab = $('.tab');
const $tabPanel = $('.tab-panel');
const targetID = '#' + $(this).attr('aria-controls');
$tab.attr('aria-selected',false).attr('aria-expanded',false); //一旦全てのタブの選択を解除
$(this).attr('aria-selected',true).attr('aria-expanded',true); //現在のタブを選択中に変更
$tabPanel.attr('aria-hidden',true); //一旦全てのタブパネルを非表示
$(targetID).attr('aria-hidden',false); //現在のタブパネルを表示
});
});
</script>