Tailwind CSSで作成したUIライブラリの色をアプリケーションごとにカスタマイズする方法
はじめに
この記事ではTailwind CSSを利用して開発したUIライブラリを複数のアプリケーションで使用する際、基本的なコンポーネントの機能やスタイルはそのままに色だけをアプリケーションごとにカスタマイズする方法について説明します。
このような要件は特にブランドやプロダクトのアイデンティティに合わせてUIを調整したい場合に役立ちます。
目的
UIライブラリで定義したコンポーネントのスタイル
アプリケーションAではUIライブラリのデフォルトの色を使用
アプリケーションBではUIライブラリの色を変更して使用
普通に実装した場合の挙動
UIライブラリ
tailwind.config.jsで定義した色を使用してボタンコンポーネントを作る
colors: {
// brand
primary: '#2563EB' // blue
}
アプリケーション
UIライブラリのCSSをimportして、Buttonコンポーネントを使用する。
import 'my-ui-lib/style.css'
import { Button } from 'my-ui-lib/Button'
export const Component = () => {
return <Button>ボタン</Button>
}
当然UIライブラリで定義したスタイルとなる。
アプリケーションAの要件は満たせるがアプリケーションBの要件が満たせない。
結果 | アプリケーションAでやりたいこと | アプリケーションBでやりたいこと |
---|---|---|
実装方針
- UIライブラリで色の定義
CSS変数を活用してUIライブラリ内の色を定義する。
これにより後からアプリケーション側で容易に上書き可能となる。
- Tailwind設定の前提
UIライブラリとアプリケーションで競合を避けるために異なるprefixを設定する。
- デフォルトの挙動
まずUIライブラリで定義したデフォルトのスタイルが適用されることを確認する。
- カスタマイズの適用
アプリケーションBではUIライブラリで定義したCSS変数を上書きし異なる色を適用する。
実装例
UIライブラリ
tailwind.config.jsでCSS変数を使用して色を定義する
デフォルト値も設定する。
colors: {
// brand
primary: 'var(--primary, #2563eb)',
}
アプリケーションA
UIライブラリのCSSをimportして、Buttonコンポーネントを使用する。
import 'my-ui-lib/style.css'
import { Button } from 'my-ui-lib/Button'
export const Component = () => {
return <Button>ボタン</Button>
}
UIコンポーネントで定義したデフォルト色となる。
アプリケーションB
UIライブラリで定義したCSS変数を上書きする。
UIライブラリのCSSをimportして、Buttonコンポーネントを使用する。
colors.css
:root {
--primary: #db2777; // pink
}
import 'my-ui-lib/style.css'
import './colors.css'
import { Button } from 'my-ui-lib/Button'
export const Component = () => {
return <Button>ボタン</Button>
}
Buttonコンポーネントの色がアプリケーションBで定義した色になりました🎉🎉🎉
少し変わった使い方
親要素でCSS変数を宣言する
import 'my-ui-lib/style.css'
import { Button } from 'my-ui-lib/Button'
export const Component = () => {
return <>
<div className={'[--primary:#ea580c]'}> // orange
<Button>ボタン A</Button>
<div>
<Button>ボタン B</Button>
</>
}
Buttonコンポーネントの色が親要素で定義した色になる。
スコープ外のコンポーネントは影響を受けない。
まとめ
TailwindとCSS変数を利用することでUIライブラリの色をアプリケーションごとに柔軟にカスタマイズできます。
ただしデザイントークンの二重管理など運用上の注意点もあります。
また実際に運用したわけではなく思いついたことを軽く検証して記事にしているのでフィードバックがあればコメントにてお知らせください。
Discussion