視覚障害を持つ人々はブラウザの拡大機能やカスタムCSSを使用して文字を大きくしてウェブサイトにアクセスすることがありますが、サイト側の対応が不適切だとレイアウトが崩れてしまいます。レイアウトを維持したまま文字のサイズ変更に対応する方法が、Airbnbの企業ブログで解説されています。

Rethinking Text Resizing on Web. Airbnb has made significant strides in… | by Steven Bassett | The Airbnb Tech Blog | May, 2024 | Medium

https://medium.com/airbnb-engineering/rethinking-text-resizing-on-web-1047b12d2881

視力が著しく低下してしまった人がAirbnbのページを見た時のイメージはこんな感じ。何が書いてあるのかを読み取るのは非常に困難です。



ブラウザにはズーム機能が用意されており、メニューからアクセスしたり、「Ctrl」と「+」を同時押しするショートカットを利用したりすることで任意のページのコンテンツを拡大・縮小することが可能です。



デスクトップPCなど表示領域が広い端末ではズーム機能を使用しても問題なくサービスを使えますが、モバイル端末では200%までズームするとヘッダーやフッターが大きくなってビューポートとして使用できる面積が半分になってしまい、快適にブラウジングすることができません。



そこで登場するのが「フォントのスケーリング」です。Arcなど一部のブラウザにはフォントのサイズを変更する機能が備わっており、ページのコンテンツ全てを拡大縮小するズーム機能とは違ってテキスト要素のみを拡大縮小することができるようになっています。



フォントのスケーリングを扱う上では、フォントの大きさが変更されたときに一緒に拡大縮小されるべき要素と、フォントのサイズにかかわらず一定の大きさであるべき要素を区別する必要があります。CSSにおいて、この2つの設定を分けているのが「px」「em」「rem」などの単位です。

「px」は画面上の1ピクセルを表す単位で、px単位で大きさを指定されたコンテンツは常に一定の大きさでレンダリングされます。「rem」「em」は共にフォントサイズからの相対的な大きさを指定する単位です。下図は3つの単位それぞれで大きさを指定した例で、最初はフォントサイズが16pxに設定されています。



フォントサイズを20pxに拡大すると「px」単位で大きさを指定した要素は変化がありませんが、「rem」「em」で指定した要素はフォントサイズに合わせて大きくなりました。「rem」はhtml要素のフォントサイズからの相対的な大きさのため、「0.5rem」の要素を重ねても同じ大きさで表示されますが、「em」は親のフォントサイズからの相対的な大きさのため、「0.5em」を重ねると最終的な表示サイズはかけ算されてどんどん小さくなっていきます。



rem単位は常にルート要素であるhtml要素のフォントサイズを基準とするため、複雑なレイアウトでも一貫性や予測可能性に優れています。Airbnbは「em」ではなく「rem」を使用することとし、さらに文字サイズの変更に限って「rem」を使用することでレイアウトを維持したまま文字の大きさだけを変更するようにしました。

AirbnbはCSS-in-JSシステムをreact-with-stylesからLinariaへ移行する作業を行っているところであり、両方のツールに対応するコードを書く必要がありました。Linariaでは下図の通り既存のピクセルベースの値をremに自動的に変換する新たなテーマを導入することでページごとにremの値をオーバーライドできるようにしたとのこと。



依然としてpx単位で指定を行いたい部分については大文字の「Px」を使用することで対応したと述べられています。



react-with-stylesでの対応においては、withStyles関数のラッパーを用意し、変換を回避する機能を与えながらフォントサイズに自動で変換されたremの値を付与するようにしたとのこと。



また、Text Resizerを使用してフォントサイズが変更されたときにどう見えるかをチェックしながら調整を行い、最終的にフォントサイズを2倍にしても読みやすさを維持できるレイアウトが完成しました。