Tailwind CSS のモディファイア制御にtailwind-mergeを利用する

Tailwind CSS のモディファイア制御にtailwind-mergeを利用する

Tailwind CSS を利用する際にはモディファイアの制御に注意する必要があります。

以下のようなシンプルなTextコンポーネントがあったとして

type Props = { children: React.ReactNode };

export function Text({ children }: Props) {
  return <p className="px-2">{children}</p>;
}

isWideなどのpropsがある場合のみに px-4に変更したいとします。

clsxなどのclass制御用のライブラリを利用すると以下のような指定で制御できそうな気がします。

import { clsx } from "clsx";

type Props = {
  isWide?: boolean;
  children: React.ReactNode;
};

export function Text({ isWide = false, children }: Props) {
  return (
    <p
      className={clsx("px-2", {
        "px-4": isWide,
      })}>
      {children}
    </p>
  );
}

しかし上記の指定だと書き出されるHTMLは以下になります。

<p class="px-2 px-4">....</p>

ブラウザ上ではpx-2px-4に打ち消されて目的の挙動になりますが、これは目的のclassの優先度が高い場合のみの話で上書きたいclassが必ずしも優先度が高くなるわけでは有りません。

そこで登場するのがtailwind-mergeです。

clsxなどと記述は似ていますが以下のように指定すると重複したclassをマージして後から指定したclassのみ表示されるようになります。

import { twMerge } from "tailwind-merge";

type Props = {
  isWide?: boolean;
  children: React.ReactNode;
};

export function Text({ isWide = false, children }: Props) {
  return (
    <p
      className={twMerge(
        "px-2", 
        isWide && "px-4"
      )}>
      {children}
    </p>
  );
}

tailwind-mergeとは別にモディファイア制御に利用されるライブラリとしてTailwind Variantsがありますので好みのライブラリをモディファイア制御に採用するとよいでしょう