Tailwind CSS로 디자인 시스템 구축

발행: (2025년 12월 18일 오후 02:49 GMT+9)
6 min read
원문: Dev.to

I’m happy to translate the article for you, but I don’t have the full text of the post. Could you please paste the content you’d like translated (excluding the source line you already provided)? Once I have the text, I’ll translate it into Korean while preserving the original formatting, markdown, and any code blocks or URLs.

개요

“Tailwind는 유틸리티 클래스입니다. 디자인 시스템에서도 사용할 수 있나요?”
답변: 네. 실제로 아주 잘 작동합니다.

디자인 시스템의 핵심은 일관성입니다—정해진 규칙을 따르는 색상, 간격, 타이포그래피 및 기타 토큰들. Tailwind는 그 일관성을 강제합니다:

  • p-4는 항상 16 px입니다.
  • text-sm는 항상 14 px입니다.

개발자 간 변동이 없습니다.

기본 구조

Design Tokens (CSS Variables)

Tailwind Config (tailwind.config)

Utility Classes (bg-primary, text-sm)

Components

1. 색상 토큰

// tailwind.config.ts
export default {
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#eff6ff',
          100: '#dbeafe',
          500: '#3b82f6', // base
          600: '#2563eb', // hover
          700: '#1d4ed8', // active
        },
        gray: {
          50: '#f9fafb',
          100: '#f3f4f6',
          500: '#6b7280',
          900: '#111827',
        },
      },
    },
  },
};

이제 bg-primary-500, text-gray-900을 사용할 수 있습니다.

CSS 변수 사용이 더 좋습니다

/* globals.css */
:root {
  --color-primary-500: #3b82f6;
  --color-primary-600: #2563eb;
}

.dark {
  --color-primary-500: #60a5fa;
  --color-primary-600: #3b82f6;
}
// tailwind.config.ts
export default {
  theme: {
    extend: {
      colors: {
        primary: {
          500: 'var(--color-primary-500)',
          600: 'var(--color-primary-600)',
        },
      },
    },
  },
};

다크 모드 전환이 이제 자동으로 이루어집니다.

2. 타이포그래피

// tailwind.config.ts
export default {
  theme: {
    extend: {
      fontSize: {
        'display-lg': ['48px', { lineHeight: '1.2', fontWeight: '700' }],
        'display-md': ['36px', { lineHeight: '1.2', fontWeight: '700' }],
        'heading-lg': ['24px', { lineHeight: '1.4', fontWeight: '600' }],
        'heading-md': ['20px', { lineHeight: '1.4', fontWeight: '600' }],
        'body-lg':    ['18px', { lineHeight: '1.6' }],
        'body-md':    ['16px', { lineHeight: '1.6' }],
        'body-sm':    ['14px', { lineHeight: '1.6' }],
      },
    },
  },
};
// Example usage in a component
<h1 className="text-display-lg">Large Title</h1>
<h2 className="text-display-md">Medium Title</h2>
<p className="text-body-md">Body text</p>

반응형 타이포그래피

CSS 변수는 반응형을 쉽게 만들어 줍니다:

:root {
  --fs-display-lg: 36px;
}

@media (min-width: 1024px) {
  :root {
    --fs-display-lg: 48px;
  }
}
// tailwind.config.ts
export default {
  theme: {
    extend: {
      fontSize: {
        'display-lg': ['var(--fs-display-lg)', { lineHeight: '1.2' }],
      },
    },
  },
};

이제 단일 text-display-lg 클래스가 모바일과 데스크톱 크기를 모두 처리합니다.

3. 간격

Tailwind의 기본 간격은 대부분의 경우에 충분하지만, 사용자 정의 스케일을 정의할 수 있습니다:

// tailwind.config.ts
export default {
  theme: {
    extend: {
      spacing: {
        xs: '4px',
        sm: '8px',
        md: '16px',
        lg: '24px',
        xl: '32px',
        '2xl': '48px',
        '3xl': '64px',
      },
    },
  },
};
{/* padding: 16px, margin‑bottom: 24px */}

실제로 Tailwind의 내장 간격(p-4, mb-6 등)—8 px 그리드—은 종종 충분합니다.

4. 컴포넌트 만들기

토큰을 설정했으면 재사용 가능한 컴포넌트를 만들 수 있습니다.

// Button.tsx
const variants = {
  primary:   'bg-primary-500 text-white hover:bg-primary-600',
  secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
  outline:   'border border-primary-500 text-primary-500 hover:bg-primary-50',
};

const sizes = {
  sm: 'h-8  px-3 text-body-sm',
  md: 'h-10 px-4 text-body-md',
  lg: 'h-12 px-6 text-body-lg',
};

export function Button({ variant = 'primary', size = 'md', ...props }) {
  return (
    // component implementation here
  );
}

cva 로 타입‑안전하게

import { cva, type VariantProps } from 'class-variance-authority';

const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md font-medium',
  {
    variants: {
      variant: {
        primary:   'bg-primary-500 text-white hover:bg-primary-600',
        secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
      },
      size: {
        sm: 'h-8  px-3 text-body-sm',
        md: 'h-10 px-4 text-body-md',
        lg: 'h-12 px-6 text-body-lg',
      },
    },
    defaultVariants: {
      variant: 'primary',
      size:    'md',
    },
  }
);

type ButtonProps = VariantProps<typeof buttonVariants>;
// { variant?: 'primary' | 'secondary'; size?: 'sm' | 'md' | 'lg' }

자동 완성과 타입‑체크가 이제 내장되었습니다.

5. 프리셋으로 배포하기

여러 프로젝트 또는 팀에서 재사용 가능한 프리셋을 생성합니다:

// my-preset.ts
const myPreset = {
  theme: {
    extend: {
      colors:   { /* … */ },
      fontSize: { /* … */ },
    },
  },
};

export default myPreset;
// tailwind.config.ts
import myPreset from './my-preset';

export default {
  presets: [myPreset],
  // project‑specific additions go here
};

Design System Checklist

  • 색상 토큰 (primary, secondary, gray, danger, success)
  • 타이포그래피 스케일 (display, heading, body, label)
  • 스페이싱 시스템 (8 px 그리드 권장)
  • 보더 반경
  • 그림자
  • 기본 컴포넌트 (Button, Input, Card 등)

정부 프로젝트용

한국 정부 프로젝트를 진행할 때는 KRDS(Korean Design System)를 따라야 합니다.
색상 코드, 폰트 크기, 간격 등 모든 요소가 엄격히 정의되어 있어 수동으로 설정하려면 하루가 걸릴 수 있습니다.

HANUI – TailwindCSS용 KRDS 프리셋

HANUI는 KRDS 토큰을 미리 적용한 Tailwind 프리셋을 제공하므로, 즉시 규격에 맞는 UI를 구축할 수 있습니다.

Tailwind 설정

// tailwind.config.ts
import hanuiPreset from '@hanui/react/tailwind.preset';

export default {
  presets: [hanuiPreset],
};

컴포넌트에서 KRDS 클래스 사용

// Example component
<div className="text-krds-body">
  KRDS styled text
</div>

<button className="krds-button">
  KRDS button
</button>

제공되는 내용

  • Colors – 완전 KRDS‑준수 팔레트
  • Typography – 올바른 폰트 패밀리, 크기 및 줄 높이
  • Responsive design – KRDS 가이드라인을 따르는 내장 브레이크포인트
  • Tech stack – TailwindCSS, React, CSS 변수, CVA (class‑variance‑authority)

위 모든 요소 덕분에 디자인 시스템을 일일이 재구성하는 대신 기능 구현에 집중할 수 있습니다.

Back to Blog

관련 글

더 보기 »

플랫폼 요소 소개

새 제품의 일부로, 이제 사전 구축된 UI 블록 및 액션 세트를 사용하여 애플리케이션에 직접 기능을 추가할 수 있습니다. Vercel for Platforms of pr...