최근 진행한 프로젝트에서는 팀의 디자인 가이드를 반영해서 tailwind.config.ts를 커스터마이징해서 사용했다.
그 과정을 정리해두면 다음 프로젝트나 리팩토링 때도 참고하기 좋을 것 같아 기록해둔다.
1. 기본설정
pnpm add -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
* 설정 파일을 .ts로 쓰고 싶으면 Vite에서는 tailwind.config.ts로 작성해도 됨.
2. px → rem 변환 유틸 추가
왜 px 대신 rem을 쓰는가?
1) 사용자 접근성 (Accessibility) 향상
- 브라우저에서 기본 폰트 사이즈를 키우면 rem 단위는 함께 커지지만, px은 고정된 크기라 변하지 않음.
- 즉, rem을 쓰면 시력이 좋지 않은 사용자도 브라우저 설정으로 쉽게 가독성을 높일 수 있음.
- 예: 시니어 대상 서비스, 공공 웹 등에서 중요하게 다룸
2) 일관된 반응형 시스템 구성
- 전체 디자인 시스템을 기준 폰트 사이즈(보통 16px = 1rem)로 통일하면, spacing, font-size, padding 등 모든 단위가 통일되어 설계가 훨씬 쉬움.
- figma 기준이 px이더라도 px → rem으로 자동 변환하면 디자인-개발 간의 소통 비용도 줄어듦.
3) 기기 해상도 및 확대 설정 대응
- 고해상도 화면, 모바일, 웹뷰 등 다양한 환경에서도 유연하게 대응 가능.
- 특히 zoom 대응에서 rem 단위는 더 자연스럽게 확대/축소됨.
Tailwind에서는 fontSize, spacing, width, height 등을 모두 커스터마이징할 수 있다.
이걸 rem 단위로 한꺼번에 바꾸기 위해 아래와 같은 함수를 만들었다.
/**
* px 단위를 rem으로 변환한 객체를 생성
* @param end 최대 px 값 (ex. 40 → 0~40까지 변환)
* @param baseFontSize 기준 폰트 사이즈 (보통 16px)
*/
const pxToRem = (end: number, baseFontSize: number = 16): Record<number, string> => {
return Object.fromEntries(
Array.from({ length: end + 1 }).map((_, i) => {
const remValue = (i / baseFontSize).toFixed(3); // 소수점 3자리까지
return [i, `${parseFloat(remValue)}rem`]; // 0: '0rem', 1: '0.0625rem', ...
}),
);
};
- 이렇게 하면 0px부터 40px까지 자동으로 rem 단위로 매핑되어 아래처럼 tailwind 설정에 쓸 수 있다.
fontSize: {
...pxToRem(40)
}
spacing: {
...pxToRem(100)
}
3. 커스텀 폰트 설정
팀에서 사용하는 폰트를 tailwind.config.ts에 등록해서 Tailwind의 font-family 유틸리티로 쉽게 적용할 수 있도록 했다.
fontFamily: {
pretendard: ['Pretendard', 'ui-sans-serif', 'system-ui'],
tech: ['Orbitron', ...defaultTheme.fontFamily.sans],
mono: ['Roboto Mono', ...defaultTheme.fontFamily.mono],
space: ['Space Grotesk', ...defaultTheme.fontFamily.sans],
}
- pretendard: 기본 본문용
- tech: 테크/디지털 느낌 강조할 때
- mono: 코드 블럭이나 시스템 로그용
- space: 약간 감각적인 UI 요소 강조용
Tailwind에선 font-pretendard, font-tech 같은 클래스명으로 바로 사용 가능하다.
4. 폰트 사이즈 시스템 정의
Figma에서 정의된 텍스트 스타일을 기준으로 fontSize를 구성했다.
Tailwind 기본 단위를 그대로 쓰기보단 display/header/body 등으로 이름을 지정해서 의미 기반 사용이 가능하게끔 설정.
fontSize: {
...pxToRem(50), // 0~50px까지 기본 rem 매핑
display01: ['3.75rem', { lineHeight: '5.625rem', fontWeight: '600' }],
display02: ['2.5rem', { lineHeight: '3.75rem', fontWeight: '600' }],
header01: ['1.75rem', { lineHeight: '2.625rem', fontWeight: '700' }],
body01: ['0.875rem', { lineHeight: '1.313rem', fontWeight: '700' }],
body04: ['0.875rem', { lineHeight: '1.313rem', fontWeight: '400' }],
d2coding01: ['0.875rem', {
lineHeight: '1.313rem',
fontWeight: '400',
letterSpacing: '-4%'
}],
}
디자인 시스템에서 text-display01, text-body04 등으로 바로 사용 가능하도록 네이밍.
5. 컬러 시스템 구성
회색은 100단계부터 1300단계까지 촘촘하게 나눴고,
상태값에 대응되는 blue/green/red/yellow 계열도 명확히 구분해서 설계함.
colors: {
icon: '#505050',
danger: '#E00000',
container: '#F7F7F7',
gray: {
100: '#FCFCFC',
200: '#F5F5F5',
...
1300: '#141414',
},
blue: {
100: '#F5F7F9',
200: '#F5FAFF',
...
1000: '#0341A3',
},
green: {
100: '#F5FFF8',
...
900: '#006A20',
},
red: {
100: '#FFF5F5',
...
900: '#610000',
},
yellow: {
100: '#FFFBEB',
...
900: '#987B06',
},
}
- gray: 배경, 테두리, 본문 텍스트 등에 단계적으로 사용
- blue: 주 색상 (버튼, 포커스 등)
- green: 성공 메시지
- red: 오류/실패
- yellow: 경고/주의
- Tailwind 클래스 bg-gray-300, text-blue-700, border-red-500 같은 식으로 쉽게 적용 가능함.
6. 기타 설정
1) Box Shadow
boxShadow: {
primary: '0px 0px 20px 0px rgba(51, 51, 51, 0.50)',
secondary: '0px 0px 20px 0px rgba(51, 51, 51, 0.20)',
tooltip: '0px 0px 4px 0px rgba(0, 0, 0, 0.2)',
}
2) Width / Height / Padding / Margin 등
아까 만든 pxToRem() 함수로 아래 속성들도 일괄 rem 단위로 지정해둠
width: pxToRem(1920),
height: pxToRem(1080),
padding: pxToRem(500),
margin: pxToRem(500),
gap: pxToRem(100),
borderWidth: pxToRem(30),
borderRadius: pxToRem(30),
- 전체 디자인 시스템이 rem 기반으로 통일되어 있고, 반응형/접근성/확장성을 모두 고려한 구조.
Tailwind CSS는 기본 설정만으로도 꽤 잘 갖춰져 있지만, 이렇게 커스터마이징해두면 프로젝트만의 스타일 시스템이 생기는 느낌이라 좋다. 사용할 때도 훨씬 편하고, 확장성이나 유지보수 면에서도 확실히 이득임. 앞으로 다른 프로젝트에서도 이 설정을 바탕으로 계속 발전시켜볼 생각이다.
'Dev > 개발기록' 카테고리의 다른 글
React 상태관리 라이브러리, 언제 뭐 써야 할까? (2) | 2025.06.10 |
---|---|
프론트엔드에서 마주치는 HTTP 304 Not Modified, 어떻게 대처할까? (0) | 2025.06.09 |
React 초기 개발 환경 구성 with Vite, Tailwind, TypeScript (0) | 2025.02.25 |