はじめに
Tailwind CSSを使っていると、className
がどんどん長くなって読みにくくなってしまうこと、ありませんか?
<button className="px-4 py-2 rounded-md border border-gray-300 bg-white text-black shadow-sm font-medium hover:cursor-pointer disabled:opacity-50">
Next
</button>
このように、基本スタイル・色・状態ごとのクラスが一列に並ぶと、
- 何がどの用途のスタイルなのか?
- 状態(hover/disabled)に関する記述はどこ?
といった情報が一目で分かりづらくなります。
解決策: .join(" ")
でclassNameを整理する
配列の .join(" ")
を使えば、論理的な意味ごとにクラスを分けて読みやすく整理できます。
✨ 書き直し例
<button
className={[
// 基本の見た目(レイアウト・タイポグラフィ)
"px-6 py-2 rounded-md border shadow-sm font-medium",
// 色(背景・枠線・文字)
"border-gray-300 bg-white text-black",
// 状態(hover時)
"hover:bg-gray-100 hover:cursor-pointer",
// 状態(無効時)
"disabled:opacity-50 disabled:cursor-not-allowed",
].join(" ")}
>
Next
</button>
👀 こうすることで得られるメリット
- 構造が視覚的に把握しやすくなる
- 差分の管理がしやすくなる(デザインの微調整や差し替えが楽)
- 状態ごとのスタイルが明確に分離される
- Tailwindの「ユーティリティファースト」の思想にもフィット
実例:CTAボタンコンポーネント
たとえば、CTA(Call To Action)ボタンを作る場合、下記のように構成ごとにスタイルを分割するとチームでも読みやすくなります。
CTAButton.jsx
interface CTAButtonProps {
disabled?: boolean;
children: React.ReactNode;
}
export const CTAButton = ({ disabled, children }: CTAButtonProps) => {
return (
<button
disabled={disabled}
className={[
// Layout & Font
"inline-flex items-center justify-center px-5 py-2 rounded-lg font-semibold",
// Colors
"bg-blue-600 text-white",
// Hover State
"hover:bg-blue-700",
// Disabled State
"disabled:bg-blue-300 disabled:cursor-not-allowed disabled:opacity-60",
// Transition
"transition-colors duration-200",
].join(" ")}
>
{children}
</button>
);
};
これなら、クラスの意味が一目でわかる上、追加・削除・条件分岐も容易です。
補足:classnamesやclsxを使ってもOK
より柔軟に条件分岐したいときは classnames
や clsx
の使用もおすすめです:
npm install classnames
import classNames from "classnames";
const buttonClass = classNames(
"px-4 py-2 rounded",
{
"bg-blue-500 text-white": !disabled,
"bg-gray-300 text-gray-600 cursor-not-allowed": disabled,
}
);
おわりに
Tailwind CSSは非常に便利ですが、長いclassNameを読みやすく保つ工夫が必要です。
今回紹介した .join(" ")
を使った書き方はシンプルかつ汎用的で、誰でもすぐに取り入れられます。
チーム開発やデザイン調整の効率も大きく変わってくるので、ぜひ日々の実装で試してみてください!