LIFULL Creators Blog

LIFULL Creators Blogとは、株式会社LIFULLの社員が記事を共有するブログです。自分の役立つ経験や知識を広めることで世界をもっとFULLにしていきます。

アクセシビリティ対応のついでに色々やった話

こんにちは。エンジニアの中島です。 現在はアクセシビリティ推進グループ(以下推進グループ)に在籍しています。

以前同組織の紹介記事をいくつかあげましたが、その通り弊社は自社の運営するサービスをアクセシブルにするため日々奮闘しています。

www.lifull.blog

www.lifull.blog

以前の記事ではどういったマインドで同組織ができたか、どのように推進しているかについて話ました。

今回は、そういった活動の中でいくつか技術的な副産物が生まれたのでその話をしようと思います。

キーボード操作編

アクセシビリティ対応にあたって、基本的なやることの一つにUIをキーボード操作可能にするという作業があります。

自社のサービスにもキーボード操作不能ないくつかのUIの存在を認識しており、それらを実際に直していくということをしています。

修正時、場合によってはJavaScriptを記述する必要があるのですが、それにあたって我々の採用しているStimulusというライブラリに若干の不満がありました。(概ね気に入っています)

それはHTML側からみて宣言的に記述することを良しとする同ライブラリの指針に対してキーボードイベントのハンドラを宣言的に記述することが難しいというところにあります。

Stimulus3.1まではキーボードイベントにフックして何らかの処理を記述する場合、以下のように書きます。

<button type="button" role="tab"
  data-action="keydown->tab#moveLeft keydowon->tab#moveRight"
>タブ1</button>
// tab_controller.js
...
moveLeft(evt) {
  if (evt.key !== 'ArrowLeft') { return; }
  // タブを一個左に切り替える
}

moveRight(evt) {
  if (evt.key !== 'ArrowRight') { return; }
  // タブを一個右に切り替える
}

keydownが発生した時にmoveLeftとmoveRightが動くというところまではHTML側から理解できますが、この実装では、"どのキー"を押した時に動作するふるまいなのかまで説明されておらず、読み手の関心はJavaScriptの実装にまで到達してしまいます。

これに不満を感じていたのでStimulus自身に本件のIssueとPRをなげて3.2で取り込んでもらうに至りました。

github.com

stimulus.hotwired.dev

これによりStimulusでも今までより宣言的に記述できるようになり、UIのふるまいに対する関心をHTMLに封じ込めることができるようになりました。

<button type="button" role="tab"
  data-action="keydown.left->tab#moveLeft keydowon.right->tab#moveRight"
>タブ1</button>

CSSの概念距離

UIの修正は時にはHTML, JavaScriptだけでは完結せず、CSSの修正が必要なケースもあります。 ただ、長年運用され続けている巨大なサービスにおいては、思いもよらぬ依存と向き合わなければならないこともあります。

AというUIを直そうとしたら、それがBというCSSに依存していて、さらにそのBはCという別のページのよく似たUIにも適応されていて...といった厄介な依存です。

少しの深さの依存なら把握できても、とても深い依存になるとなかなか一筋縄ではいきません。

これはHTMLとCSSの概念距離が開いているが故に起きる問題です。

world.hey.com

qiita.com

両者の距離が開くことで片方がまた別の何かとの依存を起こしやすくなっているのです。

恥ずかしながらいくつかの実装にあたってこの依存起因で表示崩れを起こしてしまい、緊急対応を行いました。 そうしたことをしているうちに、継続的に直していくには(これはアクセシビリティ対応だけにとどまらず)この概念距離をなくしていかないとニッチもサッチもいかないなと感じました。

そこでこの概念距離をなくしてHTMLとCSSがぴったり一対一で対応するようにTailwind CSS(UtilityCSSのライブラリ)を導入しました。

tailwindcss.com

こぼれ話のこぼれ話ですが、導入にあたり、サイト内でベースとなるfont-sizeが100%だったり62.5%だったりと揺れていた問題が浮き彫りになりました。 その問題はテンプレートを再起的にパースして62.5%の適用されたテンプレートで参照されているCSS、そうじゃないCSSを分類し、CSSパーサでtransformをかけて単位を合わせるといったことをして乗り越えました。

Tailwind CSSはスタンドアロンでも動作するようになっており、わざわざ利用者側がPostCSSを導入しなくても、内包しているPostCSSを利用して動作させることができます。 メンテナンスコストの面から考えて、なるべくパーサ系ライブラリとの依存を小さくしたいと考え、このスタンドアロンな挙動にのっかりたいと考えました。

しかし、リリースにあたって、キャッシュバスティングの機構も同時に必要だったので、Tailwind CSSが内包しているPostCSSにキャッシュバスティングの手製プラグインを適応させたところうまく動作しないことがわかりました。

キャッシュバスティングとは ブラウザがキャッシュされた古いファイルを参照し続けないようにするための機構 (パスやクエリにファイルのダイジェスト値を入れたりするケースが多い)

ソースを読んでみたところ、どうやらTailwind CSSは内部でPostCSSを利用しているものの、そこで最終的に生成されるファイル名情報に関しては破棄して動くようになっているようでした。

そこで、Tailwind CSSに対して内包するPostCSSで生成されたファイル名情報を尊重する実装をPRで提案したところ、数日のうちに取り込んでいただけました。

github.com

こちらはTailwind CSS 3.2.5で搭載される予定になっています。

さいごに

何か作業するにあたっていくつかの困難と向き合い、そちらに作業がスライドしていくyak shavingはエンジニアの宿命なのかもしれません。

いろんな作業を通してスパイラル的によりよい改善が行えるとよいなと思います。


最後までお読みいただきありがとうございました。LIFULL では共に働く仲間を募集しています!

hrmos.co

hrmos.co