2015年はアクセシビリティに関わる案件をやったりしていたので、特に WCAG 2.0 やらの対応が必要とは言われてない案件でも意識するようになったりしました。
そんな中で、タブ実装が必要な案件が有ったので、WAI-ARIA をマークアップに取り入れたタブを実装してみました。

せっかくやってみたので、今回は機能自体はとてもシンプルだけど、WAI-ARIA をマークアップに取り入れたアクセシブルなタブを紹介するです。
「WAI-ARIA ってなにそれ?おいしいの?」みたいな方や「単純にシンプルなタブを使いたい!」って方でも使えると思います。


見た目は一切整えてないのでひどいもんですが、以下がサンプルになります。

JSは aria-hidden、aria-selected の値を変えるのに使っているだけなので、マークアップも自由度が高いですし、CSSで好きにデザインを当てる事ができます。
カッコ( ・∀・)イイ!!タブをサクッと実装って感じじゃないですが、JS側で余計なことはしていないので、案件ベースだと使いやすいのかなぁと思います。
デフォルトのタブを変更するには、aria-selected、aria-hidden の値の true と false を変更すればOKです。

今回のタブのマークアップは、以下の加藤さまの記事で使われてるサンプルほぼそのままです。

記事内に、

aria-hidden、aria-selected の値は、タブの切り替えにあわせて変更する必要があります。JavaScript を使用してタブ切り替えを実装するなら大して難しくはないですね。

って書いてるなら、ついでにそのJSも書いておいてくれればいいのに!とかちょっと思いつつ読んでました。はい。

と言うわけで、以下のJSを使えば、アクセシビリティに配慮したシンプルなタブが実装できます。一応、HTMLとCSSも載せておきます。

JS(jQuery)

!function($) {
  $.fn.selectTab = function(options) {
    options = $.extend({}, $.fn.selectTab.defaultOptions, options);
    this.on('click.selectTab', function(event) {
      event.preventDefault();
      var $this = $(this)
        , tabDisp = options.tabDisp
        , panelDisp = options.panelDisp
        , slctAria = '#'+$this.attr(options.panelId)
        , $tablist = $this.parents('[role="tablist"]')
        , $tabArea = $(slctAria).parent()
      ;
      if($(slctAria).size() < 1) return false;
      $tablist.find('a').attr(tabDisp, false);
      $this.attr(tabDisp, true);
      $tabArea.children('[role=tabpanel]').not(slctAria).attr(panelDisp, true);
      $(slctAria).attr(panelDisp, false);
    });
  };
  $.fn.selectTab.defaultOptions = {
    tabDisp: 'aria-selected'
    , panelId: 'aria-controls'
    , panelDisp: 'aria-hidden'
  };
}(jQuery);
$(function(){
  $('[role=tab]').selectTab();
});

JSはお友だちにちゃちゃっと書いてもらいました、ありがとうございます。
この記事の主な部分が「aria-hidden、aria-selected の値をJSで変更」なので、ボクは何もしてない!

HTML

<ul role="tablist">
  <li><a aria-controls="tab-01" aria-selected="false" href="#tab-01" role="tab">タブ1</a></li>
  <li><a aria-controls="tab-02" aria-selected="true" href="#tab-02" role="tab">タブ2</a></li>
  <li><a aria-controls="tab-03" aria-selected="false" href="#tab-03" role="tab">タブ3</a></li>
</ul>
<div class="tabpanel-wrap">
  <div aria-hidden="true" id="tab-01" role="tabpanel">
    <p>タブ1のコンテンツ</p>
  </div>
  <div aria-hidden="false" id="tab-02" role="tabpanel">
    <p>タブ2のコンテンツ</p>
  </div>
  <div aria-hidden="true" id="tab-03" role="tabpanel">
    <p>タブ3のコンテンツ</p>
  </div>
</div>

Sass

[role="tabpanel"] {
  display: none;
  &[aria-hidden="false"] {
    display: block;
  }
}
[role="tablist"] {
  [aria-selected="true"] {
    font-weight: bold;
  }
}

CSS

[role="tabpanel"] {
  display: none;
}
[role="tabpanel"][aria-hidden="false"] {
  display: block;
}
[role="tablist"] [aria-selected="true"] {
  font-weight: bold;
}

これだけだと、見栄えがよろしくなくてイメージ沸かないかも知れないので、CSSでそれっぽくしたサンプルも作ってみました。

サンプルを見る

CSSでも opacity 使えばクロスフェードっぽくなりますし、transform 使えば色んな動きが付けられるので色々試してみるのも面白いと思います。

後、このサンプルのZIPも用意しておきました。
なんかあんまり整理してなくて汚いですが...

ZIPをダウンロード

今回ご紹介したサンプルを使うと、タブの部分だけ WAI-ARIA をマークアップに取り入れる事になるので、それもちょっと違和感有りますが、何にもしないよりは良いのかなと。
もし WAI-ARIA に少し興味を持ったなら、role 属性を定義するくらいならカンタンに出来ますので、徐々に取り入れていくのも良いのかなと思います。

...自戒を込めてるんですよ!埃被ったこのブログもなんとかせねばなーと。
この記事の一つ前の掲載日見てびっくりしたのは内緒です。