slickのアクセシビリティを調べる:前編

JavaScript

アクセシビリティとは

Web ページが、操作方法が制限される人、マウスなどで操作できない人など、あらゆる人物や環境に配慮しているかどうか、ということ。
英文字だと a と y の間に 11 文字あるから、a11y と呼ばれる。

HTML には WAI-ARIA がある。
要素に rolearia- のような属性を指定して、要素が持つ役割や目的を支援技術が読み取れるようにする。

海外では、アクセシビリティの不備が訴訟に繋がることも多い。
つまりエンジニアがアクセシビリティで消耗するのは避けられない事態となる。

roleとaria-とは

role は、その要素がもつ「役割」を、支援技術に伝えるために必要な属性である。
例えば role="dialog" 属性があれば、その要素はダイアログと伝えらえる。
単純なウィジェット的なロール(ウィジェットロール)から、 navigationbanner など場所を示すロール(ランドマークロール)まで種類が色々ある。

aria- は、その属性が持つ状態、プロパティを指定できる。
例えば aria-hidden という属性で、非表示 / 表示という状態を示すことができる。

HTML5 の要素は、それ自体が役割を明示しているものが存在する。
例えば nav 要素は navigation という役割があるため、role="naviation" を指定するのは二重指定となり怒られる。
めんどくせぇぞ ARIA!

slickとは

https://kenwheeler.github.io/slick/
jQuery 依存のスライダー&カルーセル用プラグイン。
導入が楽なので、jQuery を使用するページに取り入れられることが多い。
多くのプラグインには、アクセシビリティを考慮した属性付きの要素が生成される。
この slick もその1つ。

slickの設置

CodePenで cdn 版 slick を読み込み、accessibility が true または false のslickをそれぞれ設置。
arrow(進む、戻るボタン)と dots(●のナビ)を追加する。
https://codepen.io/dkrk/pen/aQXZrO

そして生成された DOM を見ていく。

.slick-arrowを見る

まず、「前後のスライドに移動する」ボタンにあたる、 slick-arrow の部分。

slick-prev を見ていく。

<button class="slick-prev slick-arrow" aria-label="Previous" type="button" style="">Previous</button>

以下の属性が確認できた。

  • aria-label

aria-label

生成されたボタンには、このように aria-label 属性がつけられている。
aria-label については、以下のように述べられている。

aria-label 属性の使用 - Accessibility | MDN
ARIA6: オブジェクトのラベルを提供するために aria-label を使用する | WCAG 2.0 達成方法集

要は目的を示していないオブジェクトに対して、ラベルを付けますよ、という要素。
そして、その要素にテキストがあるなら、代わりに aria-labelledby という属性をつけ、そのオブジェクトとラベルを関連づける必要がある。

これ、そもそも Previous というテキストがあって、オブジェクトの目的をちゃんと示せている。
だから aria-labelledby 属性を使って、「前後に移動するボタンの一部」であることを示した方が優しい。

slick-slideを見る

スライド部分 .slick-slide を見る。
汚いので余計な属性と class は省いた。

<li class="slick-slide" aria-hidden="false" tabindex="0" role="tabpanel" id="slick-slide00" aria-describedby="slick-slide-control00">1</li>

以下の 4 つが確認できる。

  • aria-hidden
  • tabindex
  • role="tabpanel"
  • aria-describedby

aria-hidden

まず、aria-hidden から。
true の要素と false の要素がある。

Accessible Rich Internet Applications (WAI-ARIA) 1.0 日本語訳

要素が一部のユーザーアクションの後にのみ可視である場合、著者はaria-hidden属性をtrueに設定しなければならない。要素が提示される場合、著者はaria-hidden属性をfalseに設定しなければならないか、要素が表示されていることを示す、属性を削除しなければならない。

「しなければならない」だらけ。
要は見えない要素には、aria-hidden を true にするなり非表示にしなければならない。
このスライドは見えている要素が 3 つあるので、5、1、2 のスライドが false になる。
その先のスライドは、画面外にあって見えてないので true にする。

<li class="slick-slide slick-active" aria-hidden="false" tabindex="-1">5</li>
<li class="slick-slide slick-current slick-active slick-center" aria-hidden="false" tabindex="0" role="tabpanel" id="slick-slide00" aria-describedby="slick-slide-control00">1</li>
<li class="slick-slide slick-active" aria-hidden="false" tabindex="0" role="tabpanel" id="slick-slide01" aria-describedby="slick-slide-control01">2</li>
<li class="slick-slide" aria-hidden="true" tabindex="0" role="tabpanel" id="slick-slide02" aria-describedby="slick-slide-control02">3</li>

CodePen のサンプルでは、slick をスライドして、
端のスライドが表示されるタイミングで、aria-hidden が切り替わっているのが確認できる。

非表示にするというのは、
display:none;visibility: hidden;hidden 属性がついた要素など。

tabindexについて

次に、 tabindex
アクセシビリティにも関わる、重要な属性のひとつ。

tabindex - HTML: HyperText Markup Language | MDN

キーボード(TAB キーなど)で要素間を移動する時のフォーカス設定となる。
全ての。slick-slide 要素を見ると、0 と-1 のどちらかが設定されていることがわかる。
-1 の要素は、キーボードで到達できない場所となる。

tabindex の数値は、1 以上の正の数を指定することもできる。
1,2,3…と、フォーカスの順番を指定させることができる。
ただ、0 と-1 だけを用いることが推奨されている。
正の数を指定することは、アクセシビリティ的にも推奨されていない。
順番を指定して死にかけた話が、調べるとたくさん出てくる。

CSS による配置はタブ順序には影響せず、要素の視覚的な順序のみを変更します。タブ順序は DOM 上の順序に対応します。

順番を変えるなら CSS でやれ、そういうことだろう。

また、「対話型コンテンツでないものに使用することは避けてください」とある。
対話型コンテンツとは、下記の要素を指す。

<a>, <button>, <details>, <embed>, <iframe>, <keygen>, <label>, <select>, <textarea>

li は対話型コンテンツではない気がする。

role="tabpanel"

tabpanel というロールがついている。

Accessible Rich Internet Applications (WAI-ARIA) 1.1

tablistに含まれるtabに関連づけられた、リソースのあるコンテナ。著者はtabにaria-controls属性を用いてtabpanelを参照するか、tabpanelにaria-labelledby属性を用いてtabを参照するかのいずれかの方法で、tabpanelをtabに関連付けるべきである。tablistは一般的に、通常は先行する一連のtabpanelの近くに配置される。(※以下省略)

原文では SHOULD が大文字 Bold で表記されている。
要は tabpaneltab が結びついてないといけない。
しかもその tab は、tablist に含まれているものである。

tablist どれだろうと思って ul 以下を見たら、buttondiv が入っててカオスだった。

<ul class="slider js-slide01 slick-initialized slick-slider slick-dotted">
  <button class="slick-prev slick-arrow" aria-label="Previous" type="button" style="">Previous</button>
  <div class="slick-list draggable" style="padding: 0px 50px;">
    <div class="slick-track" style="opacity: 1; width: 5908px; transform: translate3d(-2954px, 0px, 0px);">
      <li class="slider-item slick-slide slick-cloned" data-slick-index="-4" aria-hidden="true" tabindex="-1" style="width: 422px;">2</li>
        〜〜〜〜

aria-describedby

slick-slide-control00 とか、スライドの index に対応した説明付けが行われている。
中身が「1」なのに説明が controll00 とか、混乱しそうだ。

これは、.slick-dotsaria-controls と微妙に連動していることがわかった。
ということで、次は。slick-dots を見ていく。
次回へ続く。