【スタイル自由】ヘッドレスUIライブラリの紹介
こんにちは、株式会社Gizumoでエンジニアをしている田中です。
サービスを開発するときに工数削減のためにMUIやChakraUI等のUIコンポーネントライブラリを使いたいけど、独自のUI要件や変更を考慮すると導入に勇気がいるという事はありませんか?
今回はそんな懸念を解決してくれるヘッドレスUIライブラリについてご紹介します。
目次
前提・対象とする読者
この記事は以下を前提として読み進めてください。
- サンプルコードは
ReactとTypeScriptで記述 - 環境構築や必要なライブラリすべてについては触れない
- 例として出すUIコンポーネントライブラリは
Reactに対して提供されているものを中心としている
また、対象とする読者は以下のような方を想定しています。
- UIコンポーネントライブラリ導入を検討中で機能は欲しいけどスタイルは自由に行いたいという希望をお持ちの方
ReactやVue等のJavaScriptのUIフレームワークを知っている方・触ったことがある方
ヘッドレスUIライブラリとは
ヘッドレスUIライブラリとは、スタイルを持たないUIコンポーネントを提供するライブラリです。その代わり、機能とアクセシビリティのみを提供します。そのためライブラリの機能提供に乗っかりながら独自のUIを構築できます。
今回はヘッドレスUIライブラリの1つである、HeadlessUIを使用して実際にコンポーネントを作成しながらヘッドレスUIライブラリの使い方やメリット・デメリットについて見ていきます。HeadlessUIはTailwindCSSの作成元が作っているライブラリで相性が良いためTailwindCSSも同時に使用します。
MyTabsコンポーネントの作成
HeadlessUIが提供してくれるTabというコンポーネントを使用してMyTabsコンポーネントを作成します。MyTabsコンポーネントは最終的に以下のようなUIを持ちます。各タブをクリックすると、対応するコンテンツが表示されます。

最小構成
今回作成するTabコンポーネントの最小構成は以下のコードです。Tabが実際のボタンでそれに応じたコンテンツがTab.Panelです。
import { Tab } from '@headlessui/react';
export const MyTabs = () => {
return (
<Tab.Group>
<Tab.List>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
</Tab.List>
<Tab.Panels>
<Tab.Panel>Tab 1 content</Tab.Panel>
<Tab.Panel>Tab 2 content</Tab.Panel>
<Tab.Panel>Tab 3 content</Tab.Panel>
</Tab.Panels>
</Tab.Group>
);
};最低限の見た目
上記コードの見た目は以下のようになります。スタイルがいっさい付与されていません。しかし、MyTabsはすでに機能しており、各タブをクリックするとコンテンツが切り替わります。
HTML出力結果
上記コードのHTMLを見ると、以下のようになっています。Tab.Groupは出力されず、Tab.ListとTab.Panelsがdivタグとして出力されています。詳細を見ると、それぞれにrole属性やaria-属性等が付与されており、アクセシビリティへの考慮が確認できます。
MDN Tabの実装を見ると、機能とアクセシビリティを考慮したタブ機能を作るのにかなりの記述量を必要とすることが伺えます。HeadlessUIのコンポーネントを配置するだけでMDNのページと同等レベルの実装を実現できていることが確認できます。
※aria-属性はスクリーンリーダー等の支援技術に要素の状態や性質を認識させるために使用します。

スタイルを付与する
スタイルを付与したコードは以下になります。
TailwindCSSと@headlessui/tailwindcssというプラグインを使用しています。このプラグインを使うと、ui-selected:bg-whiteのように状態に応じたスタイルを付与できます。このプラグインを使うとclassNameに変数が入らず可読性の向上を見込めるのと、状態:スタイルのように記述するため要素の状態とスタイルのマッピングが明確になります。
import { Tab } from '@headlessui/react';
export const MyTabs = () => {
return (
<Tab.Group>
<Tab.List className="flex items-center gap-24 rounded-xl p-2 bg-yellow-400">
<Tab className="p-4 rounded-md bg-transparent ui-selected:bg-white text-white ui-selected:text-yellow-400">
Tab 1
</Tab>
<Tab className="p-4 rounded-md bg-transparent ui-selected:bg-white text-white ui-selected:text-yellow-400">
Tab 2
</Tab>
<Tab className="p-4 rounded-md bg-transparent ui-selected:bg-white text-white ui-selected:text-yellow-400">
Tab 3
</Tab>
</Tab.List>
<Tab.Panels className="mt-2 rounded-xl bg-purple-600 p-12">
<Tab.Panel className="text-white font-bold text-lg">
Tab 1 content
</Tab.Panel>
<Tab.Panel className="text-white font-bold text-lg">
Tab 2 content
</Tab.Panel>
<Tab.Panel className="text-white font-bold text-lg">
Tab 3 content
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
);
};スタイルを付与した見た目
上記コードの結果になります。

ヘッドレスUIライブラリのメリット・デメリット
メリット
- 自由なスタイリングが可能
- 機能とアクセシビリティの実装工数削減
メリット:自由なスタイリングが可能
ヘッドレスUIライブラリを使用すれば、自由なスタイリングが可能なため独自のUI要件やUI変更に柔軟に対応できます。たとえばプロダクト独自のデザインシステム等にも対応可能です。MUIやChakraUI等のUIコンポーネントライブラリではこの対応は難しく、一貫性を保つためにデザイナーさんとの密な連携が必要になります。連携工数の削減という意味でもヘッドレスUIライブラリは有用です。
メリット:機能とアクセシビリティの実装工数削減
ヘッドレスUIライブラリを使用すれば、機能とアクセシビリティの実装が不要なため本質的な機能開発に集中できます。たとえばMyTabsコンポーネントをスクラッチ実装するとstateで選択の状態を持ちつつ、パネル部分は分岐が必要です。ヘッドレスUIライブラリを使えばその実装をコンポーネントを置くだけで簡単かつ宣言的に実装できます。工数削減と記述量も減るため可読性向上にもつながります。
デメリット
- ライブラリ選定が難しい
- スタイリングに工数が必要
デメリット:ライブラリ選定が難しい
ヘッドレスUIライブラリはまだ、「これを使っておけばOK」というものが存在しないように思います。たとえばGitHubのスター数を見ているとMUI等のUIコンポーネントライブラリよりも成熟しきっていない印象を受けます。また、ヘッドレスUIライブラリに関する記事も多くはないため、実装例を参考にすることが難しいです。
デメリット:スタイリングに工数が必要
ヘッドレスUIライブラリは0からのスタイリング工数が必要です。スタイリングにはTailwindCSS等のライブラリを使用することが多いため、ライブラリの学習コストも発生します。MUIやChakraUIのようにコンポーネントを置くだけで見た目まで完結するわけではないため、選定の際にはスタイリング工数を考慮事項として持っておくことは重要です。
※ただし、スタイリングを自由にしたい目的のもとヘッドレスUIライブラリを選定するため、スタイリング工数をデメリットと捉えるかは選定時の要件次第ということになります。
ヘッドレスUIライブラリの紹介
最後にヘッドレスUIライブラリをいくつか紹介して終わりにしたいと思います。以下に紹介しているライブラリは比較的有名なものをピックアップしています。他にも多くのライブラリが存在しますので、興味があれば調べてみてください。
Headless UI
- スター数:
約20k(2023/06時点) TailwindCSSと作成元は同じで相性が良いです。コンポーネントはシンプルで使いやすい印象です。コンポーネントの提供数は10種類と少ないです。技術記事は比較的投稿されている印象です。
radix-ui
- スター数:
約10k(2023/06時点) - コンポーネント単位でプロジェクトにインストール可能でバンドルサイズを抑えます。会社単位で管理されているプロジェクトであり直近のコミット履歴から運用保守の面でも安心です。また、stitches、colors、iconなどのモジュールも提供されておりデザインシステムの構築まで可能です。技術記事も多く上がっており、とても注目されている印象です。
react-aria
- スター数:
約8.8k(2023/06時点) - adobe社が提供しているプロジェクトです。
Hooksベースになっており、プリミティブなDOM要素に対して、Hooksから取り出したpropsを展開して使用します。DOM要素を自由に配置できカスタマイズが容易な分Hooksベースは少し難易度が高いかもしれません。HPには多くのコンポーネントが紹介されています。技術記事はあまり見ない印象です。
ariakit
- スター数:
約6.8k(2023/06時点) - フォーム系のコンポーネントが豊富です。HPのユースケースがわかりやすく導入には優しそうです。技術記事はほとんど投稿されていない印象です。