개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Tailwind CSS — Utility First CSS 프레임워크

2026년 6월 12일
CSSTailwind CSS스타일링

CSS를 작성하는 전통적인 방식은 HTML에 클래스명을 붙이고, 별도의 CSS 파일에 스타일을 정의합니다. 이 접근법은 두 파일을 오가며 작업해야 하고, 클래스명 충돌이나 사용하지 않는 스타일 누적 같은 문제를 낳습니다.

Tailwind CSS는 다른 방향을 선택합니다. flex, p-4, text-lg처럼 단일 CSS 속성에 대응하는 작은 클래스들을 HTML에 직접 조합합니다. 별도의 CSS 파일을 작성하지 않아도 되며, 빌드 시 실제로 사용된 클래스만 포함되므로 번들 크기가 작습니다.

설치

npm install tailwindcss @tailwindcss/vite

Vite 기반 프로젝트의 경우 vite.config.ts에 플러그인을 추가합니다.

// vite.config.ts
import tailwindcss from "@tailwindcss/vite";

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

CSS 진입점 파일에 임포트를 추가합니다.

/* index.css */
@import "tailwindcss";

1. Utility Class

Tailwind의 각 클래스는 CSS 속성 하나를 담당합니다. 여러 클래스를 조합하여 원하는 스타일을 만듭니다.

<!-- 기존 방식 -->
<div class="card">내용</div>

<style>
.card {
  display: flex;
  padding: 16px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
</style>

<!-- Tailwind 방식 -->
<div class="flex p-4 bg-white rounded-lg shadow-sm">내용</div>

자주 사용하는 유틸리티 클래스 목록입니다.

클래스CSS 속성
flexdisplay: flex
p-4padding: 1rem
mt-2margin-top: 0.5rem
text-lgfont-size: 1.125rem
font-boldfont-weight: 700
text-gray-700color: #374151
bg-blue-500background-color: #3b82f6
rounded-mdborder-radius: 0.375rem
w-fullwidth: 100%
hiddendisplay: none

숫자 스케일은 대부분 0.25rem(4px) 단위입니다. p-1은 4px, p-2는 8px, p-4는 16px입니다.


2. Responsive Design

Tailwind는 모바일 퍼스트 방식을 사용합니다. 접두사 없는 클래스가 기본(모바일) 스타일이고, sm:, md:, lg:, xl: 접두사를 붙이면 해당 브레이크포인트 이상에서 적용됩니다.

<!-- 모바일: 1열, 태블릿: 2열, 데스크탑: 3열 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  <div>항목 1</div>
  <div>항목 2</div>
  <div>항목 3</div>
</div>

<!-- 모바일: 세로 정렬, 데스크탑: 가로 정렬 -->
<div class="flex flex-col lg:flex-row items-center gap-6">
  <img class="w-full lg:w-48" src="..." />
  <p class="text-sm lg:text-base">설명 텍스트</p>
</div>

3. Breakpoint

Breakpoint: 반응형 스타일이 전환되는 기준 뷰포트 너비

Tailwind의 기본 브레이크포인트는 다음과 같습니다.

  0px         640px       768px       1024px      1280px      1536px
  |           |           |           |           |           |
  [  (default) ]
              [    sm:     ]
                          [   md:     ]
                                      [   lg:     ]
                                                  [   xl:     ]
                                                              [ 2xl: ]

tailwind.config.js에서 커스텀 브레이크포인트를 추가하거나 기본값을 덮어쓸 수 있습니다.

// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      tablet: "640px",
      laptop: "1024px",
      desktop: "1280px",
    },
  },
};

4. Theme

tailwind.config.js의 theme 섹션에서 프로젝트 디자인 시스템을 정의합니다. extend를 사용하면 기본값을 유지하면서 추가합니다.

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50: "#eff6ff",
          500: "#3b82f6",
          900: "#1e3a8a",
        },
        // 사용법: text-brand-500, bg-brand-50
      },
      fontFamily: {
        sans: ["Pretendard", "sans-serif"],
        mono: ["JetBrains Mono", "monospace"],
      },
      spacing: {
        18: "4.5rem",  // p-18, m-18 등으로 사용
        22: "5.5rem",
      },
      borderRadius: {
        "4xl": "2rem",
      },
    },
  },
};
<button class="bg-brand-500 hover:bg-brand-900 font-sans px-18 rounded-4xl">
  커스텀 테마 버튼
</button>

5. Variant

Variant는 CSS의 가상 클래스(pseudo-class)와 가상 요소(pseudo-element)를 클래스 형태로 표현합니다.

<!-- 인터랙션 상태 -->
<button class="bg-blue-500 hover:bg-blue-700 active:scale-95 transition-all">
  버튼
</button>

<!-- 폼 상태 -->
<input class="border focus:outline-none focus:ring-2 focus:ring-blue-500
              disabled:opacity-50 disabled:cursor-not-allowed" />

<!-- 그룹 상태 — 부모에 group, 자식에 group-hover: -->
<div class="group cursor-pointer">
  <img class="group-hover:scale-105 transition-transform" src="..." />
  <p class="text-gray-600 group-hover:text-blue-600">제목</p>
</div>

<!-- 가상 요소 -->
<p class="before:content-['★'] before:text-yellow-400 before:mr-1">
  추천 항목
</p>

자주 사용하는 Variant 목록입니다.

Variant적용 조건
hover:마우스 호버
focus:포커스 상태
active:클릭/탭 중
disabled:disabled 속성
dark:다크 모드
first:첫 번째 자식
last:마지막 자식
odd: / even:홀수/짝수 자식
group-hover:부모 hover 시
peer-focus:형제 focus 시

6. Plugin

Plugin: Tailwind의 기본 유틸리티를 확장하거나 새로운 클래스를 추가하는 확장 시스템

공식 플러그인과 커뮤니티 플러그인으로 기능을 확장합니다.

npm install @tailwindcss/typography @tailwindcss/forms
// tailwind.config.js
module.exports = {
  plugins: [
    require("@tailwindcss/typography"),  // prose 클래스로 마크다운 스타일
    require("@tailwindcss/forms"),        // 폼 요소 기본 스타일 초기화
  ],
};

커스텀 플러그인을 직접 작성할 수도 있습니다.

const plugin = require("tailwindcss/plugin");

module.exports = {
  plugins: [
    plugin(function ({ addUtilities, addComponents, theme }) {
      // 커스텀 유틸리티 추가
      addUtilities({
        ".text-balance": { "text-wrap": "balance" },
        ".scrollbar-hide": {
          "-ms-overflow-style": "none",
          "scrollbar-width": "none",
        },
      });

      // 커스텀 컴포넌트 추가
      addComponents({
        ".btn-primary": {
          backgroundColor: theme("colors.blue.500"),
          color: "white",
          padding: `${theme("spacing.2")} ${theme("spacing.4")}`,
          borderRadius: theme("borderRadius.md"),
        },
      });
    }),
  ],
};

7. Configuration

tailwind.config.js는 Tailwind의 핵심 설정 파일입니다.

/** @type {import('tailwindcss').Config} */
module.exports = {
  // 1. content: 클래스를 스캔할 파일 경로
  // 여기 명시된 파일에서 사용된 클래스만 최종 CSS에 포함됨
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],

  // 2. theme: 디자인 토큰 정의
  theme: {
    extend: {
      colors: { brand: "#0ea5e9" },
    },
  },

  // 3. darkMode: 다크 모드 전략
  darkMode: "class", // "media" 또는 "class"

  // 4. plugins: 플러그인 목록
  plugins: [
    require("@tailwindcss/typography"),
  ],
};

content 설정이 잘못되면 빌드된 CSS에서 클래스가 누락됩니다. 동적으로 생성된 클래스명(템플릿 리터럴 등)은 스캔되지 않으므로 전체 클래스명을 문자열로 작성해야 합니다.

// 잘못된 방식 — 스캔 불가
const color = "blue";
<div className={`text-${color}-500`} />

// 올바른 방식 — 전체 클래스명 사용
const classMap = { blue: "text-blue-500", red: "text-red-500" };
<div className={classMap[color]} />

8. Dark Mode

Tailwind는 media와 class 두 가지 다크 모드 전략을 제공합니다.

media 전략: 운영체제의 색상 모드 설정을 따릅니다.

// tailwind.config.js
darkMode: "media",

class 전략: html 또는 루트 요소에 dark 클래스가 있을 때 적용됩니다. JavaScript로 토글할 수 있어 더 유연합니다.

darkMode: "class",
// 다크 모드 토글 구현
function ThemeToggle() {
  const toggleDark = () => {
    document.documentElement.classList.toggle("dark");
  };

  return <button onClick={toggleDark}>테마 전환</button>;
}

// dark: 접두사로 다크 모드 스타일 적용
<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">
  <h1 class="text-2xl font-bold text-blue-600 dark:text-blue-400">제목</h1>
  <p class="text-gray-600 dark:text-gray-300">본문 내용</p>
  <button class="bg-blue-500 dark:bg-blue-700 text-white px-4 py-2 rounded">
    버튼
  </button>
</div>

CSS 변수와 조합하면 테마를 더 체계적으로 관리할 수 있습니다.

/* index.css */
:root {
  --color-bg: 255 255 255;
  --color-text: 17 24 39;
}

.dark {
  --color-bg: 17 24 39;
  --color-text: 243 244 246;
}
// tailwind.config.js
colors: {
  bg: "rgb(var(--color-bg) / <alpha-value>)",
  text: "rgb(var(--color-text) / <alpha-value>)",
}

정리

Tailwind CSS는 CSS 작성 방식을 바꿉니다. 클래스명을 고민하지 않아도 되고, 스타일 파일과 마크업 파일을 오갈 필요가 없습니다. 팀 전체가 동일한 디자인 토큰을 공유하므로 일관성 있는 UI를 유지하기 쉽습니다.

처음에는 클래스가 길어 낯설게 느껴질 수 있습니다. 그러나 요소의 스타일을 파악하기 위해 CSS 파일을 찾아다닐 필요가 없다는 점에서 가독성이 오히려 높아집니다.

← 이전 글Storybook — UI 컴포넌트를 독립적으로 개발하고 문서화하는 도구
다음 글 →TanStack Query — 서버 상태를 캐시하고 동기화하는 라이브러리