本文へジャンプ

ウェブアクセシビリティに配慮したtableの列固定に挑戦してみた

Posted by MONSTER DIVE

界隈で徐々に盛り上がってきているウェブアクセシビリティ熱。
その波に乗り遅れまいと、ようやく本格的に勉強・実践を始めました。

このたびウェブアクセシビリティ レベルAに準拠することが要件のお仕事をいただきまして、勉強しながら取り組んでいるところです。
そんな私の前に立ちはだかったもの...それは...

列固定・横スクロールのある表

デザインデータには、表が横長〜に横たわっておりました。その下にはスクロールバー。そして、固定表示された1列目のセル...

経験上、スクロールあり+列固定のtableは、一筋縄ではいかないことを知っています。よくある実装方法としては、固定部分とスクロール部分を分けて、別tableにしてしまう方法。
ですが、それではアクセシビリティを確保することができません。ひとつのtableになっていなければ、音声読み上げ機能でそれぞれの内容を紐付けることができないからです。

悩むこと半日...

閃いた。
固定する部分を複製して、上に被せて置けばいいんじゃない?! そしてそれを読み上げないようにすればいいんじゃない?!

ということで、やってみました。

やってみたこと

HTML

HTML側では、tableを包含するdiv要素を2重に配置します。
内側のdivtableをスクロールさせる用、外側のdivは複製した1列目だけのtableを位置固定で配置する用です。

該当のtable要素には、JavaScriptから取得するためのdata-*属性(or class属性)を付けておきます。

こんな感じです。

<div class="sample-wrapper">
<div class="sample-scroll">
<table class="sample-table" data-scrollTable="true"></table>
</div>
</div>

JavaScript

JavaScriptでは、ざっくり↓こんなことをします。

  1. 該当のtableの各行1列目だけを抜き出したtableを作成します
  2. 作成したtableには、それ用のclass(例:.-copy等)を付与します(そのclassにはposition: absolute; top: 0; left: 0;等のスタイルを指定しておく)
  3. さらに音声読み上げ機能で2重に読み上げられることがないよう、aria-hidden="true"も加えておきます
  4. それを、外側のdiv要素(ここではdiv.sample-wrapper)の子要素として挿入します

これでもOKなのですが、このままだとスクロールバーが固定表示された列の下にまで広がっていて(その下に元の1列目があるから)、スクロールエリアじゃないのに、なんかカッコ悪い...ですよね...
ということで、↓以下を追加します。

  1. 作成した固定表示用のtableの横幅を取得します
  2. その数値を、内側のdiv要素(ここではdiv.sample-scroll)のmargin-leftの値に設定します(borderがある場合は、線がダブるので、その分をマイナスします)
  3. 元のtableにもclassを付与するなどして、1列目のセルを表示上つぶします(幅が0になるようにCSSで調整します)

これで、スクロールバーがスクロールするエリアだけに付く形になりました。
やったね!

まとめ

多少強引な方法ではありますが、アクセシビリティを損なうことなく、また、たとえJavaScriptが無効の状態でも問題ない(列固定なしのスクロールになるだけな)ので、まぁいいかなって。思うのですが。どうでしょう...?

まぁ、こういう横長〜の表がそもそもアクセシビリティいまいちなんじゃないのかな...って気もしなくもないですが...。
そこまで横長〜じゃなくても、レスポンシブウェブデザインで画面幅の狭い環境に対応させることにも活用できますし、いいんじゃないかなっ! (誰も褒めてくれないので、自分で自分を褒めるスタイル)

ウェブアクセシビリティの配慮、実践してみて思いましたが、要件としてアクセシビリティ対応を求められているからやる、ということではなく、これからはどんなウェブサイトでもきちんとアクセシビリティに配慮したコーディングを心がけていきたいなと。
誰でも、どこからでも、どんなデバイスからでも、情報にアクセスできるというのがウェブの良さ。それを損なうようなコーディングではいけませんよね。
より良いウェブのために自分にできることを、しっかり実践していこうと、改めて思いました。がんばろー!

追記

記事公開後、友人からありがたいご指摘をいただきましたので、追記します。(2018.2.14)

要約を付けましょう

そもそもこういう横長〜の表を否応なしに読み上げ対応させること自体が、アクセシブルではないと思う、という旨のご指摘をいただきました。
その通りですね。(まとめのところで自分でも軽〜くツッコミを入れつつもスルーしてしまっていました...ダメですね...配慮がまったく足りていませんでした。)

ということで、表の要約を加えてあげると良いですね。
要約の読み上げを聞いて、その上で詳細を見たいと思う場合には、お手数ですが表の内容を読み進めていただく。そうでない場合には、要約で概要をつかんだ上で次に進んでいただく。ということが可能になります。

さてその要約ですが、aria-describedby属性を使うのがいいかなと思います(summary属性はhtml5で廃止になってしまいましたし)。
私の検証では、残念なことにiOSのVoiceOverでは読み上げてくれませんでした...が、読み上げ機能の利用者に対して説明を付けるなら、これがいいと思うのですよね。
他になにかいい方法をご存知でしたら教えていただきたいです><

表の「ヘッダ」について

固定する列のことを、公開当初は「列ヘッダ」と表現していたのですが、列に対して「ヘッダ」という表現は適切ではない、という旨のご指摘をいただきました。
確かに、どう表現したら良いのか(伝わるのか)悩んだ部分ではあります。

ヘッダというのはtheadで表現される表頭のことで、行に対して使用すべき表現だそうです。
なので、「列ヘッダ」と書いていたところを「1列目」「固定表示された列」等の表現に修正いたしました。

合わせて、本来表には正しい意味でのヘッダが必要とのことなので、サンプルページの表にもヘッダの行を追加いたしました。(あまり良いサンプルでなくて申し訳ないです...)

追記のまとめ

マークアッパーとしましては(なのかどうかわからないですけども)、与えられたデザイン・与えられたデータ・与えられた条件の中で、なんとかしようとしてしまいがちですが、そもそもその形でないといけないの?!というところから考えてみることも必要かもしれません。
ということに、ご指摘をいただき気付くことができました。
横長〜でスクロールしないと見られない表なんて、目で見てマウスで操作できる人であっても、決して見やすいとは言えないかもですし...。

制限の中でなんとかするのもお仕事ですが、他のより良い伝え方を探るのもお仕事ですよね、そうですよね。
今回は全体的に配慮の足りなさを知ることとなり、とても良い経験になりました。ご指摘くださった友人の皆さま、また応援・協力してくださった友人の皆さまに感謝です!

Recent Entries
MD EVENT REPORT
What's Hot?