Afaik

TailwindCSS

TailwindCSS 의 장점과 단점은 무엇이고 사용하는데에 어려움은 없었나요?

TailwindCSS유틸리티 퍼스트(Utility-First) 접근 방식을 사용하는 CSS 프레임워크입니다. 기존의 컴포넌트 기반 CSS 프레임워크(Bootstrap 등)와는 달리, 미리 정의된 작은 유틸리티 클래스들을 조합하여 스타일을 구성합니다.

TailwindCSS란?

TailwindCSS는 HTML에 직접 클래스를 적용하여 스타일링하는 방식입니다. 예를 들어 bg-blue-500 text-white px-4 py-2처럼 여러 유틸리티 클래스를 조합합니다.

TailwindCSS의 장점

1. 빠른 개발 속도

<!-- 기존 CSS 방식 -->
<style>
  .button-primary {
    background-color: #3b82f6;
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 0.375rem;
    border: none;
    font-weight: 500;
    transition: background-color 0.2s;
  }
  .button-primary:hover {
    background-color: #2563eb;
  }
</style>
<button class="button-primary">클릭하세요</button>

<!-- TailwindCSS 방식 -->
<button
  class="rounded bg-blue-500 px-4 py-2 font-medium text-white transition-colors hover:bg-blue-600"
>
  클릭하세요
</button>

장점:

  • CSS 파일을 별도로 작성할 필요 없음
  • HTML 안에서 바로 스타일링 가능
  • 클래스명을 고민할 시간이 절약됨

2. 일관된 디자인 시스템

<!-- 색상 팔레트가 미리 정의되어 일관성 유지 -->
<div class="border border-blue-200 bg-blue-50">
  <h3 class="font-semibold text-blue-900">제목</h3>
  <p class="text-blue-700">내용</p>
  <button class="bg-blue-500 text-white hover:bg-blue-600">버튼</button>
</div>

<!-- 간격도 일관된 scale로 관리 -->
<div class="space-y-4">
  <!-- 16px 간격 -->
  <div class="p-2">2 * 0.25rem = 0.5rem 패딩</div>
  <div class="p-4">4 * 0.25rem = 1rem 패딩</div>
  <div class="p-8">8 * 0.25rem = 2rem 패딩</div>
</div>

3. 불필요한 CSS 제거 (PurgeCSS)

// tailwind.config.js
module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx}", // 이 경로의 파일들만 스캔
  ],
  // 실제 사용된 클래스만 최종 CSS에 포함
};

결과: 개발 시에는 모든 유틸리티 클래스가 포함되지만, 빌드 시에는 실제 사용된 클래스만 포함되어 CSS 파일 크기가 대폭 줄어듭니다.

4. 반응형 디자인이 쉬움

<!-- 화면 크기별로 다른 스타일 적용 -->

<!-- 기본: 작은 텍스트 -->
<!-- 768px 이상: 보통 텍스트 -->
<!-- 1024px 이상: 큰 텍스트 -->

<!-- 기본: 1열 -->
<!-- 768px 이상: 2열 -->
<!-- 1024px 이상: 3열 -->
<div
  class="grid-cols-1 text-sm md:grid-cols-2 md:text-base lg:grid-cols-3 lg:text-lg"
>
  <!-- 내용 -->
</div>

5. 커스터마이징이 용이

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        "brand-blue": "#1e40af",
        "brand-green": "#059669",
      },
      spacing: {
        72: "18rem", // 새로운 간격 추가
        84: "21rem",
        96: "24rem",
      },
      fontFamily: {
        sans: ["Noto Sans KR", "sans-serif"],
      },
    },
  },
};

TailwindCSS의 단점

1. HTML이 복잡해짐

<!-- 클래스가 많아서 읽기 어려워짐 -->
<button
  class="inline-flex items-center justify-center rounded-md border border-transparent bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-colors duration-200 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
>
  복잡한 버튼
</button>

해결책:

// 컴포넌트로 추상화
const Button = ({ children, variant = "primary", ...props }) => {
  const baseClasses =
    "inline-flex items-center justify-center px-4 py-2 text-sm font-medium rounded-md transition-colors duration-200";
  const variantClasses = {
    primary: "text-white bg-blue-600 hover:bg-blue-700",
    secondary: "text-gray-700 bg-gray-200 hover:bg-gray-300",
  };

  return (
    <button className={`${baseClasses} ${variantClasses[variant]}`} {...props}>
      {children}
    </button>
  );
};

2. 학습 곡선

<!-- 이 클래스들이 뭘 의미하는지 외워야 함 -->
<div
  class="flex flex-col space-y-2 rounded-lg border border-gray-200 bg-gray-50 p-4 shadow-sm sm:flex-row sm:space-x-4 sm:space-y-0"
></div>

신입 개발자에게는 다음이 어려울 수 있습니다:

  • flex-colflex-direction: column인 것
  • sm: 접두사가 @media (min-width: 640px)를 의미하는 것
  • space-y-2가 자식 요소들 사이에 세로 간격을 주는 것

3. 디자이너와의 협업 어려움

<!-- 디자이너가 이해하기 어려운 코드 -->
<div class="bg-gradient-to-br from-purple-400 via-pink-500 to-red-500">
  <!-- 디자이너: "이게 무슨 색상이죠?" -->
</div>

실제 사용 경험과 어려움

초기 학습 단계에서의 어려움

// ❌ 처음에 자주 하는 실수들
function BadExample() {
  return (
    <div>
      {/* 클래스 순서가 엉망 */}
      <div className="rounded bg-blue-500 p-4 text-white hover:bg-blue-600">
        {/* 불필요한 중복 */}
        <p className="text-lg font-bold text-white">제목</p>
        <p className="text-sm text-white">내용</p>

        {/* 반응형을 잘못 이해 */}
        <div className="w-full sm:w-2/3 md:w-1/2 lg:w-1/3">잘못된 순서</div>
      </div>
    </div>
  );
}

// ✅ 올바른 사용법
function GoodExample() {
  return (
    <div className="rounded bg-blue-500 p-4 text-white transition-colors hover:bg-blue-600">
      {/* 부모에서 색상 상속 */}
      <h3 className="text-lg font-bold">제목</h3>
      <p className="text-sm opacity-90">내용</p>

      {/* 올바른 반응형 순서: 작은 화면부터 */}
      <div className="w-full sm:w-2/3 md:w-1/2 lg:w-1/3">올바른 순서</div>
    </div>
  );
}

해결했던 실제 문제들

// 문제: 같은 스타일이 반복됨
function RepetitiveCode() {
  return (
    <div>
      <button className="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded">버튼1</button>
      <button className="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded">버튼2</button>
      <button className="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded">버튼3</button>
    </div>
  );
}

// 해결: CSS 컴포넌트 클래스 생성
/* styles.css */
@layer components {
  .btn-primary {
    @apply bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded transition-colors;
  }
}

// 또는 React 컴포넌트로 추상화
const PrimaryButton = ({ children, className = '', ...props }) => (
  <button
    className={`bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded transition-colors ${className}`}
    {...props}
  >
    {children}
  </button>
);
Edit on GitHub

Last updated on