スタイル自由でアクセシブルなHeadless UI 第1回 Headless UIの特徴と利用準備

自由に好きな方法でスタイルを当てることができ、なおかつアクセシブルなUIライブラリである、Headless UIを紹介します。まずはその特徴をつかんでみましょう。

発行

著者 高津戸 壮 テクニカルディレクター
スタイル自由でアクセシブルなHeadless UI シリーズの記事一覧

はじめに

この連載ではHeadless UIについて紹介します。

Headless UIというのは、OSSのUIライブラリです。CodeGridでも過去に紹介したTailwind CSSを開発しているTailwind Labsが中心となって開発しています。

Headless UIのトップページを見ると、Menu、Listbox、Switch、Disclosure、Dialogなど、普段Webアプリケーションでよく見かけるようなUIが並んでいるのがわかります。

こういったUIを作る際、Headless UIを使えば、自由にスタイルを制御できて、アクセシビリティも確保することができます。

  • 自由にスタイルを制御できる
  • アクセシビリティも確保できる

これがHeadless UIの特長です。重要なので2度言いました。

Headless UIはMITライセンスで公開され、2021年7月現在では、React用、Vue用の2つのパッケージとして実装されています。今回はまず、このHeadless UIがどういうものなのかについて解説します。

なお、このシリーズは、一応ReactとTailwind CSSを前提知識として設定しますが、そこまで突っ込んでこの2つの知識に精通していなくても雰囲気がわかるように書いていくつもりです。下記のシリーズも参照してください。

とりあえず、Headless UIとはこういうもの

まずは、「Headless UIというのはこういうものです」というのをざっくり理解していただくため、Headless UIを使って実装したUIを操作している様子の動画を用意しました。

まず1つ目は、Headless UIのMenu(Dropdown)を使い、本当に最小限の状態で使って作ったUIを操作している様子です。

どうでしょうか、Headless UIをそのまま使っただけだと、ただこれだけなんですよ。単に「Toggle Menu!」とテキストだけ並んでいて、それをクリックすると「Menu1」「Menu2」という、これまたテキストだけが表示される。さらに、クリックするとページが遷移する。テキストで表示されているだけなので、これだと何のことやらという感じですよね。

2つ目は、そのあとにスタイルを当てたりアニメーションを付与したものを、キーボードで操作している様子です。

スタイルが当てられているので、トグルメニューであることがわかりやすくなっています。デモの動画では、Keycastrというソフトで、入力しているキーが下に表示されるようにしています。キー操作に合わせてフォーカスが変わったりしていることが確認できます。

3つ目は、この画面をiPadで、VoiceOverをオンにして操作した様子です(この動画を再生するとVoiceOverの音声が流れるのでご注意ください)。

音声をオンにして見てもらうと、画面内に表示されているテキストのほか、「メニューポップアップ」とか「メニューアイテム」などと読み上げられているのが確認できると思います。

このように、Headless UIは、UIの振る舞いとでも言いましょうか、ざっくりいうと「スタイル以外の部分」を提供してくれるライブラリです。

「なるほど、これぞ俺の求めていたものだ!」と感じられた方は、今回の記事はサラッと読み飛ばしてもらって構わなそうです。「まだイマイチわからないな〜」という方は、次節よりこのHeadless UIのどこらへんが嬉しいのかを解説するので、じっくり読んでみてください。

スタイルが内包されているライブラリ

Headless UIは、「スタイルなし」で「アクセシブル」であると始めに紹介しました。 まずは、「スタイルなし」とはどういうことかという点について解説します。

世の中には無数のUIライブラリがあります。代表的なものとして、ここではjQuery UIを例に挙げます。

このjQuery UIを使えば、アコーディオン、ダイアログ、メニューなどのUIを、ごくわずかなコードで実装できてしまうという便利なものです。昔からWebサイト/アプリの実装をしている方は、使ったことのある方も多いのではないかと思います。

このようなUIを実装したいのであれば、jQuery UIを使うことで実装コストを大きく減らすことができるでしょう。世の中にはこのようなUIライブラリがいろいろとあり、MITライセンスなどで配布され、商用利用でも無料で使えるものが多数あります。ありがたい話です。

このjQuery UIのようなライブラリはたくさんありますが、このようなライブラリのほとんどは、UIを表現するためのスタイルも内包されているという特徴があります。つまり、jQuery UIを使えば、jQuery UIの用意したデザインのUIが画面に表示されるということです。

何を当たり前のことを言っているのかと思われるかもしれませんが、Headless UIは、それではイヤだと感じる人向けのライブラリです。Headless UIは、一番始めの動画でわかるように、スタイルが一切付いてこないのです。よって、CSSやらCSS in JSやらで、自分で一からスタイルを当てなければならないのです。

「スタイルは、調整できるじゃないですか」

「いやいや待ってくださいよ、jQuery UIはいろいろ見た目を調整できるじゃないですか」

と、そこそこjQuery UIを使ったことがある方は感じられるかもしれません。そうです。jQuery UIには、Theme Rollerという仕組みが用意されていて、以下のように、細かくスタイルを調整することができます。

さすがはjQuery UI。一時代を築いたjQueryの名を冠するライブラリなだけあります。このTheme Rollerは、jQuery UIが用意しているUIのHTMLの各要素に設定されているクラスに、外部のCSSファイルに書かれたCSSのルールでスタイルを当てることで実現されています。デザインをカスタマイズすることができるUIの大半は、このように、CSSをいじって見た目を変えたり、一部の要素に追加でクラスを指定できるように設計されているものが多いことでしょう。

こんなふうに、こういったスタイルが内包されているライブラリのデザインを調整したい場合、ライブラリが用意しているHTMLの構造を理解し、そのHTMLが基本的に変更不可能であることを前提にして実装を行う必要が出てきます。そして、この場合にどのくらいスタイルがカスタマイズ可能かは、ライブラリ次第であると言えます。jQuery UIはなかなか自由に調整できるようになっているほうだと思いますが、完全にコントロールできるわけではありません。要するに、こういったライブラリを使う場合は、「基本的に自由にスタイルをいじることができないもの」であるというのをベースに考えておくのが無難です。

その結果どうなるかというと、みんなjQuery UIの用意したデザインを使うことになります。まぁ、スタイルも内包されているライブラリなので当たり前の話ではあるんですが……。実際のところ、jQuery UIのDatepickerは、ホテルやレストランの予約サイトなどでよく見かけるんじゃないでしょうか。

アクセシビリティが考慮されていないUIライブラリ

とは言いましても、ある程度スタイルは調整可能です。jQuery UIであればそれなりにいじれるようにもなっていますし。なんとかWebサイトのデザインに合わせてスタイルを調整できたとします。しかし、アクセシブルに作られていないUIライブラリを選んでしまった場合、そのUIについてアクセシビリティを担保するのは基本的には無理と考えておいたほうが良いでしょう。

たとえば、前述のjQuery UIのDatepickerですが、タブでフォーカスしようとすると閉じてしまいます。その様子を動画に撮ったので見てみてください。

escキーを押したら閉じてくれますが、tabキーを押すとその瞬間にDatepickerが閉じてしまいます。これは、端的に言ってキーボードによる操作を十分に考慮されていないと言ってしまってよいでしょう。

この問題に対応するにはどうすればいいでしょうか。これは基本的に外側からどうこうできる問題ではないので、自分でjQuery UIのコードを改善して、jQuery UIにPull Requestを投げるのが良いでしょう。そうすれば、世の中の多くの開発者を助けることもできます。

しかし、jQuery UIを使う多くの人はそのように行動しないはずです。それは、ほとんどの場合、Datepickerを低コストで実装したいと考えてそのようなUIライブラリを選んでいるためです。アクセシビリティを考慮したかったら、別のUIライブラリを探したほうが良いでしょう。jQuery UIが作られたのはもうずいぶん昔ですからね……。

それなら、アクセシビリティにも考慮した別のライブラリを探すかもしれません。たとえば、Duet Datepickerはキーボードの操作を考慮している、優れたライブラリです。

これを操作しているところも動画に撮ったので、見てみてください。

タブや矢印キーの操作でUIを自由に操作できているのがわかるかと思います。

しかし……。

「よし!ではDuetを使おう!じゃあDuetのスタイルのカスタマイズ方法はどうやるのかな……?」
「このライブラリだとWebサイトのデザインに合わせられないな……他のを探すか……」

……という具合に、開発者は自分に真にフィットするライブラリを求めてインターネットをさまよい、そのライブラリのカスタマイズ方法を調べて日々が過ぎていくのです。

Headless UIなら2つの望みを叶える

「スタイルは自由にしたい」
「アクセシビリティも考慮したい」

両方やらなくちゃらないのが開発者のつらいところなわけですが、この2つの望みを叶えてくれるのがHeadless UIです。Headless UIを使って実装すれば、スタイルはまったく付いてきませんので、自分で自由にHTMLを組み、好きな方法でスタイルを当てることができます。そして、フォーカスの制御やスクリーンリーダーへの配慮は、Headless UIがよしなにやってくれます。

たとえば、最初に紹介したHeadless UIのDropdownのキーボード操作は、WAI-ARIA Authoring Practicesの内容を元に実装されているそうです。

ここには、ボタンのフォーカス時、Enter/Spaceを押すと1つ目のメニューアイテムにフォーカスを移すだとか、Down Arrow/Up Arrowでメニューアイテムのフォーカスを移動させるという旨が書かれています。これは、Headless UIが提供しているキー操作そのものです。

ほか、Chrome DevToolsでのぞいてみると、aria-haspopuparia-expandedなどの属性が制御されている様子を確認することができます。

……と、このような流れだとHeadless UIを使うことはメリットしかないように聞こえるかもしれませんが、実装コストとしては、スタイルも内包しているUIライブラリと比較すると高めです。それは当然、自分でHTMLをある程度書き、スタイルも自分で考えて当てなければならないためです。

アクセシビリティにもしっかり考慮されていて、デザインも問題なしのUIライブラリが存在していれば、そちらを使ったほうが実装コストとしては安くなるでしょう。たとえば先ほど紹介した、Duetのようなライブラリです。しかし、ある程度デザインのコントロールを取りたい場合は、Headless UIはなかなか良い選択肢であろうと筆者は考えています。

そんなHeadless UIの用意してくれているUIの中から、冒頭で操作している様子として紹介した Dropdown Menu と、 Transition の使い方を、この連載では紹介します。

この連載で作るもの

この連載で紹介するコードはもう作ってあるので、初めにこれらをお見せします。以下の4つです。

これらのコードは以下レポジトリに、ディレクトリを切って置いてあります。

Headless UIはReact及びVue.jsで利用できると冒頭で書きました。この連載で用意したデモは、Create React Appで作ったWebアプリの上で動作するものとして用意しました。

このあたりは、ReactだったらNext.jsGatsby、Vue.jsだったら、Vue.jsをそのまま使ったりNuxt.jsを使ったりなど、土台となる環境が多様なのが現代です。それぞれの環境に載せた場合、微調整は必要かもしれませんが、この連載ではひとまずReactのコードをデモする環境として、Reactの公式で学習するのに快適であると紹介されているCreate React Appを使うことにします。

Vue.jsを使う場合、この連載のコードはそのままは使えませんが、ほぼ同じ形で使えるよう、Headless UIは作られています。Headless UIのドキュメントでは、左上のプルダウンから「Vue」を選ぶと、Vue用のドキュメントに切り替わります。

ひとまず、この連載としては、Headless UIとはこういうものかというのをなんとなく理解していただければと考え、書いていきます。

なお、Headless UI自体は、Tailwind CSSなしでも動作するはずですが、一応Headless UI自体がTailwind CSSを使うといい感じに実装できるぞと銘打っているので、この連載ではスタイルを当てるためにTailwind CSSを使っていきます。

Preact上でもHeadless UIは動作する?

Reactとほぼ同等の機能を持ち、Reactよりもさらに軽い動作が期待できるUIライブラリにPreactがあります。筆者が軽く検証した程度ですが、Preact上でも動作することを確認しました。

React + Tailwind CSSなアプリを作る準備

Headless UIの解説をする前に、まずはその土台となる環境を用意します。Create React Appをインストールし、Tailwind CSSをセットアップします。とは言っても、以下で解説されている手順を順に踏んでいくだけです。

この内容は本連載のトピックからは外れるので、細かく解説はしません。上記手順でセットアップしたファイル一式を以下のディレクトリに置いておきました。

もし手元で試したい場合は、

npm ci
npm start

で動作し、以下のようにローカルでサーバーが立ち上がります。

この状態をデプロイしたサーバーを一応用意しました。

DevToolsで要素をinspectしてみると、Tailwind CSSのクラスによりスタイルが当てられているのを確認することができます。

今回はひとまずここまでです。次回は、ここにHeadless UIのMenuを実装していきます。