🔥

tailwindcssでclsx使うときに気をつけるべきこと

2024/12/21に公開

※この記事は「COUNTERWORKS Advent Calendar」の21日目の記事です。

はじめに

株式会社カウンターワークスでエンジニアをしている小木曽です。
フロントエンド開発でtailwindcssを採用するケースはかなり増えているかと思います。
今回は、tailwindcssでclsx使うと意図しない実装になるケースについて記事にしたいと思います。

背景

ご存知かと思いますが、tailwindcssはReactであればclassNameに直接スタイルを当てられる便利なCSSフレームワークです。
弊社では、当初はCSS Modulesを採用しており、途中からtailwindcssを導入しました。
CSS Modulesを利用していたこともあってスタイルの条件分岐はclsxというライブラリを使っておりました。
clsxとは条件に基づいてクラス名を動的に結合してくれるライブラリです。

styles.modules.scss
.classA {
  text-align: center;
}

.classB {
  color: red;
}
index.tsx
import clsx from 'clsx'
import styles from './styles.modules.scss'

<div className={clsx(styles.classA, styles.classB)}>テスト</div>

tailwindcssを導入後も条件分岐は変わらずclsxを使っていたのですが、実装の仕方を間違えると期待した動作にならないので注意が必要です。

期待した動作にならない実装例

例えば以下のような実装です。

index.tsx
const isActive = true;

<div className={clsx("w-20", isActive && "w-10")}>テスト</div>

上記の実装だとw-20が優先されます
w-20とw-10が逆でもw-20が優先されます。
tailwindcss内部のクラス定義に依存することになります。

ちなみに以下だとfont-thinが適用されます。

<div className={clsx('font-normal', 'font-thin', 'font-bold', 'font-semibold')}>テスト</div>

そのため同一のクラスを使う場合は条件分岐は正確にやるべきです。

index.tsx
const isActive = true;

<div className={clsx(isActive ? "w-10": "w-20")}>テスト</div>

改善方法

そもそも分岐しろよという話ではありますが、tailwindcssはスタイルが複雑であればあるほど、定義が長くなり、重複するクラスがでてくるのはあることか思います。
そこでtailwindcssが提供しているライブラリでの改善方法をお伝えしたいと思います。

twMergeを使う

twMergeはクラスがコンフリクトした場合、それを解消してくれます。
後勝ちになります。

index.tsx
import { twMerge } from 'tailwind-merge';

const isActive = true;

<div className={twMerge("w-20", isActive && "w-10")}>テスト</div>

結果はw-10が適用されます。

以下はp-4が適用されます。

index.tsx
<div className={twMerge('px-3', isActive && 'p-4')}>テスト</div>

後勝ちになるので、本来残したいスタイルが消えてしまう恐れもあるので注意が必要ですが、スタイルの重複を解消してくれるのでとても便利です。

tailwind-variantsを使う

綺麗にやるならこの方法だと思います。
条件によって変えたい箇所をvariantsで定義します。

index.tsx
import { tv } from 'tailwind-variants';

const button = tv(
  {
    base: 'text-white px-4 py-3',
    variants: {
      background: {
        primary: 'bg-primary',
        secondary: 'bg-secondary',
      },
    },
  },
);

<div className={button({ background: 'secondary' })}>テスト</div>

さいごに

tailwindcssを使うとスタイル付けは簡単になったのですが、その結果どのスタイルが適用されたかまで考えてなかったので私自身も勉強になりました。
スタイルでユーザーの評価は大きく変わるので気をつけましょう。

We are Hiring!

株式会社カウンターワークスでは、共に運用しやすいアプリケーション作りを考えながら事業を前進させるメンバーを募集しています!
興味のある方はぜひ以下のリンクからご応募ください!

COUNTERWORKS テックブログ

Discussion