1. はじめに:Tailwindでのカラーパレット管理
Tailwind CSSは、効率的にUIを構築するための強力なツールです。
多くのプロジェクトでは、tailwind.config.ts
で独自のカラーパレットを定義し、デザインの一貫性を保っています。
例えば、以下のように定義すれば、プロジェクト全体で使えるカラーパレットが実現できます。
// tailwind.config.ts の一例
import type { Config } from 'tailwindcss'
import scrollbarHide from 'tailwind-scrollbar-hide'
const config: Config = {
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
theme: {
extend: {
colors: {
ap: {
gray: {
DEFAULT: '#9f9f9f',
0: '#fff',
50: '#fafafa',
100: '#f5f5f5',
200: '#efefef',
300: '#e1e1e1',
400: '#bebebe',
500: '#9f9f9f',
600: '#767676',
700: '#626262',
800: '#434343',
900: '#222',
1000: '#000',
},
},
},
},
},
}
export default config
クラス名に bg-ap-gray-300
や border-ap-gray
と指定するだけで、手軽に使えるのはとても魅力的です。
使用例
👆のように定義されているとき、classNameに次のように指定することでカラーを使用することができます。
// ap-grayなど数値suffixがない場合はDEFAULTが当てられます
<div className="bg-ap-gray-300 border border-lg border-ap-gray">
<span className="text-ap-gray-1000 p-4">
hogehoge
</span>
</div>
2. 問題:SVGやfill・strokeでの苦労
しかし、ここで一つのジレンマが発生します。
ボタンや背景以外に、SVGの fill
や stroke
、もしくはJavaScript内で直接カラーコードを指定しなければならない場面では、
毎回 #9f9f9f
のようなカラーコードを手入力する必要があり、保守性が低下してしまいます。
-
問題点:
- 定義済みのカラーパレットが活かしきれない
- カラーコードの重複記述で、変更時に手間がかかる
3. 解決策:Tailwindの設定からカラーコードを動的に取得する
ここで登場するのが、Tailwindのカラーパレット設定をそのまま利用してカラーコードを返すユーティリティ関数です。
この仕組みを導入すれば、SVGやその他のコンポーネントでも、わざわざカラーコードをハードコーディングする必要がなくなります。
実装例:utils/tailwindColor.ts
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from '../../tailwind.config'
const fullConfig = resolveConfig(tailwindConfig)
export const getTailwindColor = (colorPath: string) => {
// 'ap-gray-600' や 'ap-gray-DEFAULT' の形式で指定
const colors = fullConfig.theme.colors
return colorPath.split('-').reduce((acc: any, key) => acc[key], colors)
}
この関数は、tailwind.config.ts
に定義されたカラーパレットを元に、
指定したパス文字列(例: 'ap-gray-600'
)を辿ってカラーコード(例: #767676
)を返してくれます。
利用例
const color = getTailwindColor('ap-gray-600') // → #767676 を返す
const color2 = getTailwindColor('ap-gray-DEFAULT') // → #9f9f9f を返す
また、以下のようにSVGコンポーネント内で活用することで、Tailwindで設定したカラーを容易に反映できます。(Reactのコンポーネントを例にとっています)
share-icon.tsx
import { getTailwindColor } from 'utils/tailwindColor'
type IconProps = {
fill?: string
className?: string
}
const ShareIcon = ({ fill = 'ap-black-300', className = '' }: IconProps) => {
const fillColor = getTailwindColor(fill)
return (
<svg
width="25"
height="25"
viewBox="0 0 25 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<g clipPath="url(#clip0_400_3071)">
<path
d="M16.5 5.5L15.08 6.92L13.49 5.33V16.5H11.51V5.33L9.92 6.92L8.5 5.5L12.5 1.5L16.5 5.5ZM20.5 10.5V21.5C20.5 22.6 19.6 23.5 18.5 23.5H6.5C5.39 23.5 4.5 22.6 4.5 21.5V10.5C4.5 9.39 5.39 8.5 6.5 8.5H9.5V10.5H6.5V21.5H18.5V10.5H15.5V8.5H18.5C19.6 8.5 20.5 9.39 20.5 10.5Z"
fill={fillColor}
/>
</g>
<defs>
<clipPath id="clip0_400_3071">
<rect
width="24"
height="24"
fill="white"
transform="translate(0.5 0.5)"
/>
</clipPath>
</defs>
</svg>
)
}
export default ShareIcon
次のようにアイコンにfillを渡すだけで、色分けできるようになりました!
<ShareIcon />
<ShareIcon fill='ap-red-700' />
<ShareIcon fill='ap-blue-700' />
4. なぜこのアプローチが有効なのか
-
一元管理:
Tailwindの設定に沿ったカラーパレットを、そのまま各コンポーネントで再利用できるため、メンテナンスが楽になります。 -
変更が容易:
カラーの変更が必要な場合、tailwind.config.ts
のみ修正すれば全体に反映されるため、開発スピードと正確性が向上します。 -
再利用性:
コンポーネント毎に異なるカラーコードを記述する必要がなく、コードの再利用性が向上します。
5. まとめ
Tailwind CSSでカラーパレットを一元管理しつつ、SVGやその他の場面で同一のカラーを使い回すためのこのテクニックは、コードの効率化とコードの保守性向上に貢献します。
この仕組みを採用することで、デザインの一貫性を保ちながら開発できるとおもいます。
ぜひ、感想や改善案をコメントで教えてください!
ストックついでに いいねもいただけますと幸いです!