리액트 스타일링 - Tailwind CSS

#CSS #React #TailwindCSS #TailwindCSS설치

Tailwind CSS(유틸리티 퍼스트) 개념

Tailwind CSS는 유틸리티 퍼스트 스타일링 철학을 따르는 프레임워크 중에서 가장 인기 있는 라이브러리입니다. 유틸리티 퍼스트(utility-first)란 작고 재사용 가능한 유틸리티 클래스를 조합해 스타일을 만드는 방식입니다.

Tailwind CSS는 요즘 리액트 스타일링에서 각광받고 있는 유틸리티 퍼스트 스타일링 라이브러리이다. 유틸리티 퍼스트란 스타일 속성을 가장 작은 단위로 쪼개어 재사용 가능한 클래스로 만들어두고, 이를 조합해서 사용하는 것을 말한다. Tawilwind CSS도 vanila-extract과 마찬가지로 제로 런타임이다(빌드 타임에 필요한 CSS 생성).

설치 및 기본 사용법

$npm install tailwindcss @tailwindcss/vite

vite.config.ts에 플러그인 추가

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  	plugins: [react(), tailwindcss()],
});

src 폴더에 index.css파일 생성 후 Tailwind import

// index.css
@import 'tailwindcss'

main.tsx 파일에서 index.css import

// main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import './index.css';

createRoot(document.getElementById('root')!).render(
    <StrictMode>
        <App />
    </StrictMode>
);
// App.tsx
export default function App() {
  return (
    <button className='bg-red-500 text-white'>버튼</button>
    );
}

Tailwind CSS의 사용법은 언뜻보면 정통 CSS 방식인 인라인 스타일과 비슷하지만, style 속성이 아닌 className 속성에 값을 입력해서 조합한다. 또한 인라인 스타일과 달리 가상 선택자와 미디어 쿼리(반응형) 처리가 가능하다.

className 속성에 입력하는 값은 Tailwind에서 제공하는 클래스 명이다. 클래스 명은 각각의 CSS 속성과 대응하며, :hover와 같은 가상 선택자도 입력이 가능하다. 클래스 명은 Tailwind CSS 공식 문서에서 검색하거나, VS Code의 인텔리센스 확장 프로그램을 이용하면 쉽게 찾을 수 있다.

tailwind-merge 라이브러리와 동적 스타일링

정통 스타일링 방식의 글로벌 방식이나 CSS 모듈 방식과 마찬가지로, Tailwind CSS도 클래스명 조합이 필요하다. 이 때 classnames를 사용해도 되지만, Tailwind CSS는 그보다 더 편리한 tailwind-merge 라이브러리를 제공한다.

$ npm i tailwind-merge

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

export default function App() {
  const isActive = true;
  return (
    <button className={twMerge('bg-red-500 text-white', isActive && 'bg-blue-500')}>버튼</button>
    );
}

위 예시처럼 twMerge로 클래스명 조합 및 조건부 스타일링이 가능하다.

twMerge가 classnames보다 더 유용한 이유는, 같은 속성의 클래스가 여러개 조합되면 가장 마지막에 조합된 클래스의 값만 남기기 때문이다. 위 예시의 경우 'bg-red''bg-blue'가 모두 조합되어, 마지막에 조합된 'bg-blue'만 남아 스타일 적용이 된다.

하지만 classnames를 아예 사용하지 않는 것은 아니고, 주로 clsx나 classnames로 조건부 로직을 처리한 뒤, 그 결과를 twMerge에 넣어 스타일 충돌을 해결하는 cn 함수 패턴을 많이 사용한다고 한다.