본문 바로가기

CSS/Tailwind

[Tailwind] tailwind의 필수 라이브러리 clsx, tailwind-merge, cva

Tailwind CSS와 함께 tailwind-merge, cva (Class Variance Authority), clsx를 조합하여 사용하는 방식은

각각의 라이브러리가 제공하는 기능을 결합하여 효율적인 UI 컴포넌트 관리를 가능하게 합니다. 

 

1. clsx

  • 기능: 조건부로 className을 처리하는 데 사용됩니다. 객체나 배열을 통해 조건에 따라 클래스를 추가하거나 제거할 수 있습니다
  • 예시
import clsx from 'clsx';
// or
import { clsx } from 'clsx';

// Strings (variadic)
clsx('foo', true && 'bar', 'baz');
//=> 'foo bar baz'

// Objects
clsx({ foo:true, bar:false, baz:isTrue() });
//=> 'foo baz'

// Objects (variadic)
clsx({ foo:true }, { bar:false }, null, { '--foobar':'hello' });
//=> 'foo --foobar'

// Arrays
clsx(['foo', 0, false, 'bar']);
//=> 'foo bar'

// Arrays (variadic)
clsx(['foo'], ['', 0, false, 'bar'], [['baz', [['hello'], 'there']]]);
//=> 'foo bar baz hello there'

// Kitchen sink (with nesting)
clsx('foo', [1 && 'bar', { baz:false, bat:null }, ['hello', ['world']]], 'cya');
//=> 'foo bar hello world cya'

 

https://github.com/lukeed/clsx

 

GitHub - lukeed/clsx: A tiny (239B) utility for constructing `className` strings conditionally.

A tiny (239B) utility for constructing `className` strings conditionally. - lukeed/clsx

github.com

 

 

 

2. tailwind-merge

  • 기능: 중복된 Tailwind CSS 클래스를 제거하고, 마지막에 선언된 클래스를 우선시하여 병합합니다. 이는 클래스 충돌 문제를 해결하는 데 유용합니다
  • 예시
import { twMerge } from 'tailwind-merge'

twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
// → 'hover:bg-dark-red p-3 bg-[#B91C1C]'

https://github.com/dcastil/tailwind-merge

 

GitHub - dcastil/tailwind-merge: Merge Tailwind CSS classes without style conflicts

Merge Tailwind CSS classes without style conflicts - dcastil/tailwind-merge

github.com

 

 

 

3. cva (Class Variance Authority)

  • 기능: 컴포넌트에 다양한 스타일을 맵핑할 수 있도록 도와주는 라이브러리입니다. props에 따라 className을 동적으로 생성할 수 있습니다
  • 예시
// cva(기본 클래스, 설정 객체) 형태로 버튼 스타일을 정의
const button = cva(
  // 모든 버튼에 공통으로 적용될 기본 클래스들
  ["font-semibold", "border", "rounded"], 
  {
    variants: {
      // intent 변형 - primary 또는 secondary 스타일
      intent: {
        primary: ["bg-blue-500", "text-white", "border-transparent"],
        secondary: ["bg-white", "text-gray-800", "border-gray-400"],
      },

      // size 변형 - small 또는 medium 크기
      size: {
        small: ["text-sm", "py-1", "px-2"],
        medium: ["text-base", "py-2", "px-4"],
      },

      // disabled 상태 변형 - true일 때만 스타일 적용
      disabled: {
        false: null, // false일 때는 아무 스타일도 적용하지 않음
        true: ["opacity-50", "cursor-not-allowed"],
      },
    },

    // 여러 variant 조합에 따른 추가 스타일 정의
    compoundVariants: [
      // primary + not disabled = hover 효과 추가
      {
        intent: "primary",
        disabled: false,
        className: "hover:bg-blue-600",
      },
      // secondary + not disabled = hover 효과 추가
      {
        intent: "secondary",
        disabled: false,
        className: "hover:bg-gray-100",
      },
      // primary + medium = 대문자 변환 추가
      {
        intent: "primary",
        size: "medium",
        className: "uppercase",
      },
    ],

    // variant가 지정되지 않았을 때의 기본값
    defaultVariants: {
      intent: "primary",
      size: "medium",
      disabled: false,
    },
  }
);

button(); // 기본 스타일 적용
button({ disabled: true }); // 비활성화 스타일 적용
button({ intent: "secondary", size: "small" }); // secondary 스타일의 작은 버튼

https://cva.style/docs/getting-started/variants

 

Variants | cva

Class Variance Authority

cva.style

 

 

 

조합 사용

  • clsxtailwind-merge를 결합하여 조건부 클래스 적용과 중복 제거를 동시에 처리할 수 있습니다
  • cva는 props 기반의 동적 스타일링을 제공하며, clsxtailwind-merge와 함께 사용하여 더 유연한 컴포넌트 관리가 가능합니다

차이점 요약

라이브러리 주요 기능
clsx 조건부 className 처리
tailwind-merge 중복 클래스 제거 및 병합
cva props 기반 동적 스타일링