フロントエンド開発において、スタイリングはデザインの自由度と生産性を両立させるための重要な要素です。Tailwind CSSはその手軽さとパフォーマンスで人気がありますが、より柔軟なスタイリングを求める場面もあるでしょう。一方で、CSS-in-JSのような複雑なアプローチに踏み込むのは躊躇われた経験がある方は少なくないかなと思います。そんな時におすすめしたいのが「Class Variance Authority(CVA)」です。CVAは、Tailwind CSSを活用しつつ、variantsの管理やスタイリングを簡素化するためのライブラリです1。このブログでは、CVAを利用することで、いかに効率的に自由度の高いスタイリングが可能になるかをご紹介します。
CVAのある時・ない時
CVAがどんなものかを説明するには、実際のコードを見てみるのが一番です。まずは、CVAを使わずにTailwind CSSだけでスタイリングを行う場合を考えてみましょう。
PrimaryとSecondaryの2つのVariantを持つボタンを作成するとします。この場合、以下のようなコードになるでしょう。
import type { FC, PropsWithChildren } from "react"; type Props = { variant: "primary" | "secondary"; }; export const ButtonWithoutCva: FC<PropsWithChildren<Props>> = ({ variant, children, }) => ( <button type="button" className={`px-2 py-1 rounded text-white ${variant === "primary" ? "bg-indigo-500" : variant === "secondary" ? "bg-gray-600" : ""}`} > {children} </button> );
同じコンポーネントをCVAを使って書くと、以下のようになります。
import { type VariantProps, cva } from "class-variance-authority"; import type { FC, PropsWithChildren } from "react"; const buttonVariant = cva("px-2 py-1 rounded text-white ", { variants: { variant: { primary: "bg-indigo-500", secondary: "bg-gray-600", }, }, defaultVariants: { variant: "primary", }, }); type Props = VariantProps<typeof buttonVariant>; export const ButtonWithCva: FC<PropsWithChildren<Props>> = ({ variant, children, }) => ( <button type="button" className={buttonVariant({ variant })}> {children} </button> );
cva
は、クラスのバリエーションを作成するための関数です。
これを使って、ボタンのベースクラスとバリエーションbuttonVariant
を定義しています。
共通のクラスとしてpx-2 py-1 rounded text-white
を指定し、
variants
オプションで、バリエーションを指定しています。ここでは variant
という名前で、primary
とsecondary
の二種類のバージョンを設定しています。primary
はbg-indigo-500
で、secondary
はbg-gray-600
で、それぞれ背景色を指定しています。
defaultVariants
では、デフォルトのバリエーションを指定しています。
そして、VariantProps
を使ってbuttonVariant
からプロパティの型を作ります。
ButtonWithCva
コンポーネントを利用する際、以下のようにvariant
プロパティを指定する際はdefault
かprimary
が候補として表示されます。
以下のリンクから、「CVAのある時・ない時」で作ったコンポーネントをStackblitzで使ってみることができるので、興味のある方はお試しください。
https://stackblitz.com/~/github.com/toyamarinyon/hello-cva
まとめ
Tailwind CSS使ってスタイリングをしていて、クラスの管理が煩雑になってきたな、という時にはCVAを使ってみるとスッキリするかもしれません。
Tailwind CSSとCVAを使った、大規模な実装例を見てみたい時には https://ui.shadcn.com/ を参考にしてみてください。
- Tailwind CSS以外にもCSS Modulesなどとも組み合わせることが可能ですが、本ブログではTailwind CSSを前提として説明しています。↩