17 Tailwind CSS
1. Tailwind CSS 설치
보통 웹사이트를 꾸밀 때는 별도의 CSS 작성하지만 Tailwind는 이미 만들어진 Class를 HTML에 바로 붙여서 디자인하는 방식이다.
공식사이트 치트시트1.1. 설치
과거(v3)에는 설정을 위해 자바스크립트 파일(tailwind.config.js)을 복잡하게 만져야 했으나, v4는 “CSS 하나로 모든 것이 끝나는” 방식으로 변경되었다.
- Vite
- CDN
- 터미널에 아래 명령어 입력
npm install tailwindcss @tailwindcss/vite- vite.config.js 파일에 아래 코드 추가
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' // ← 추가
export default defineConfig({
plugins: [react(), tailwindcss()],
})- src/index.css 에 아래 코드 추가
@import "tailwindcss";- HTML의
<head>태그 안에 아래의 코드를 삽입한다<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://unpkg.com/@tailwindcss/browser@4"></script> </head> <body> <h1 class="text-3xl font-bold text-blue-600 underline"> Hello, Tailwind v4! </h1> </body> </html>
- 터미널에 아래 명령어 입력
npm install tailwindcss @tailwindcss/vite- vite.config.js 파일에 아래 코드 추가
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' // ← 추가
export default defineConfig({
plugins: [react(), tailwindcss()],
})- src/index.css 에 아래 코드 추가
@import "tailwindcss";- HTML의
<head>태그 안에 아래의 코드를 삽입한다<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://unpkg.com/@tailwindcss/browser@4"></script> </head> <body> <h1 class="text-3xl font-bold text-blue-600 underline"> Hello, Tailwind v4! </h1> </body> </html>
요약
유틸리티 우선(Utility-First)
- 기존 방식:
.btn { background: blue; }클래스를 정의하고 HTML에서 적용한다. - Tailwind 방식:
class="bg-blue-500 text-white"와 같이 이미 정의된 클래스를 조합한다.
1.2. Size
- 설명
- 예시
Width
| 클래스 | 값 |
|---|---|
w-{n} | spacing 스케일 (w-4 = 16px) |
w-full | 100% |
w-screen | 100vw |
w-auto | auto |
w-1/2, w-1/3, w-2/3 | 50%, 33.3%, 66.6% |
w-1/4, w-3/4 | 25%, 75% |
w-[200px] | 임의값 |
min-w-0, min-w-full | 최솟값 |
max-w-sm ~ max-w-7xl | 최댓값 (sm=24rem~) |
Height
| 클래스 | 값 |
|---|---|
h-{n} | spacing 스케일 |
h-full | 100% |
h-screen | 100vh |
h-auto | auto |
min-h-screen | min-height: 100vh |
min-h-0 | min-height: 0 |
h-dvh | 100dvh (동적 뷰포트) |
h-svh | 100svh (소형 뷰포트) |
size 단축 클래스
| 클래스 | 값 |
|---|---|
size-10 | w-10 h-10 |
size-[200px] | w-200px h-200px |
// 1단계: w-full, h-16 — 고정 크기
<div className="w-full">가로 100%</div>
<div className="h-16">높이 64px</div>// 2단계: 비율 — 부모 기준 백분율
<div className="w-1/2">부모의 50%</div>
<div className="w-1/3">부모의 33%</div>
<div className="w-2/3">부모의 66%</div>// 3단계: max-w — 최대 너비 제한 (반응형에 자주 사용)
<div className="w-full max-w-xl">최대 576px까지만</div>
<div className="w-full max-w-4xl mx-auto">최대 너비 + 가운데 정렬</div>// 4단계: size — 가로·세로 동시 지정
<div className="size-10">40x40</div>
<div className="size-16">64x64</div>
<div className="size-[200px]">200x200</div>Width
| 클래스 | 값 |
|---|---|
w-{n} | spacing 스케일 (w-4 = 16px) |
w-full | 100% |
w-screen | 100vw |
w-auto | auto |
w-1/2, w-1/3, w-2/3 | 50%, 33.3%, 66.6% |
w-1/4, w-3/4 | 25%, 75% |
w-[200px] | 임의값 |
min-w-0, min-w-full | 최솟값 |
max-w-sm ~ max-w-7xl | 최댓값 (sm=24rem~) |
Height
| 클래스 | 값 |
|---|---|
h-{n} | spacing 스케일 |
h-full | 100% |
h-screen | 100vh |
h-auto | auto |
min-h-screen | min-height: 100vh |
min-h-0 | min-height: 0 |
h-dvh | 100dvh (동적 뷰포트) |
h-svh | 100svh (소형 뷰포트) |
size 단축 클래스
| 클래스 | 값 |
|---|---|
size-10 | w-10 h-10 |
size-[200px] | w-200px h-200px |
// 1단계: w-full, h-16 — 고정 크기
<div className="w-full">가로 100%</div>
<div className="h-16">높이 64px</div>// 2단계: 비율 — 부모 기준 백분율
<div className="w-1/2">부모의 50%</div>
<div className="w-1/3">부모의 33%</div>
<div className="w-2/3">부모의 66%</div>// 3단계: max-w — 최대 너비 제한 (반응형에 자주 사용)
<div className="w-full max-w-xl">최대 576px까지만</div>
<div className="w-full max-w-4xl mx-auto">최대 너비 + 가운데 정렬</div>// 4단계: size — 가로·세로 동시 지정
<div className="size-10">40x40</div>
<div className="size-16">64x64</div>
<div className="size-[200px]">200x200</div>1.3. Typography
1.3.1. Size,Weight,Color
-
Font Size (text-*)
text-xs /*크기12px/행간1rem */ text-sm /*크기14px/행간1.25rem */ text-base /*크기16px/행간1.5rem */ text-lg /*크기18px/행간1.75rem */ text-xl /*크기20px/행간1.75rem */ text-2xl /*크기24px/행간2rem */ text-3xl /*크기30px/행간2.25rem */ text-4xl /*크기36px/행간2.5rem */ text-5xl /*크기48px/행간1 */ text-6xl /*크기60px/행간1 */ -
Font Weight
font-thin /* 100 */
font-extralight /* 200 */
font-light /* 300 */
font-normal /* 400 */
font-medium /* 500 */
font-semibold /* 600 */
font-bold /* 700 */
font-extrabold /* 800 */
font-black /* 900 */- Text
/*색상*/
text-white
text-gray-500
text-yellow-300
text-blue-600
text-white/80 /* 투명도 포함 */
/* 정렬 */
text-left
text-center
text-right
text-justify
/* 변환 */
uppercase
lowercase
capitalize
normal-case
/* 장식 */
underline line-through no-underline overline
/* 오버플로 처리 */
truncate /* 한 줄 말줄임 */
line-clamp-2 /* 2줄 말줄임 */
line-clamp-3 /* 3줄 말줄임 */
whitespace-nowrap /* 줄바꿈 금지 */1.3.2. Letter Spacing · Line Height
/* 자간 */
tracking-tight tracking-normal tracking-wide tracking-widest
/* 행간 */
leading-none /* 1 */
leading-tight /* 1.25 */
leading-normal /* 1.5 */
leading-loose /* 2 */
leading-[1.8] /* 임의값 */
// 1단계: text-size — 글자 크기
<p className="text-sm">작은 텍스트 (14px)</p>
<p className="text-base">기본 텍스트 (16px)</p>
<p className="text-xl">큰 텍스트 (20px)</p>
<p className="text-4xl">제목용 텍스트 (36px)</p>
// 2단계: font-weight — 굵기
<p className="font-normal">일반 굵기</p>
<p className="font-bold">굵게</p>
<p className="font-black">가장 굵게</p>
// 3단계: text-color — 색상
<p className="text-white">흰색</p>
<p className="text-gray-400">회색</p>
<p className="text-yellow-400">노란색</p>
// 4단계: text-align — 정렬
<p className="text-left">왼쪽 정렬</p>
<p className="text-center">가운데 정렬</p>
<p className="text-right">오른쪽 정렬</p>
// 5단계: truncate / line-clamp — 넘치는 텍스트 처리
<p className="truncate">한 줄을 넘으면 말줄임표로 잘림...</p>
<p className="line-clamp-2">두 줄을 넘으면 잘림. 긴 텍스트 긴 텍스트 긴 텍스트 긴 텍스트...</p>
1.4. Backgrounds — 배경
1.4.1. 기본 색상 팔레트
Tailwind의 색상은 색상명-숫자 형태이다. 숫자가 클수록 어두워진다 (50 가장 밝음, 950 가장 어두움).
| 색상명 | 대표 클래스 예시 |
|---|---|
| slate, gray, zinc, neutral, stone | 무채색 계열 |
| red, orange, amber, yellow | 따뜻한 계열 |
| lime, green, emerald, teal | 초록 계열 |
| cyan, sky, blue, indigo | 파란 계열 |
| violet, purple, fuchsia, pink, rose | 보라·분홍 계열 |
1.4.2. 배경색 적용
/* 배경색 */
bg-white bg-black
bg-gray-900 bg-gray-800
bg-yellow-400 bg-blue-600
/* 투명도 (슬래시 문법) */
bg-black/50 /* background: rgba(0,0,0,0.5) */
bg-white/10 /* background: rgba(255,255,255,0.1) */
bg-black/90 /* GOFLIX 헤더에 사용 */
1.4.3. 테두리 색상
border-gray-200 border-yellow-400 border-transparent
18. GOFLIX 프로젝트 적용 예시
Header 분석
<header className="fixed top-0 left-0 w-full py-4 px-2 bg-black/90 z-50">
{/* fixed: 스크롤해도 고정 */}
{/* top-0 left-0: 화면 최상단 좌측 */}
{/* w-full: 전체 너비 */}
{/* py-4 px-2: 상하 16px, 좌우 8px 패딩 */}
{/* bg-black/90: 검은색 배경 90% 불투명 */}
{/* z-50: 다른 요소 위에 표시 */}
<div className="container mx-auto">
<Link to="/">
<h1 className="text-3xl text-yellow-300 font-bold">
{/* text-3xl: 30px 텍스트 */}
{/* text-yellow-300: 연한 노란색 */}
{/* font-bold: 굵은 글씨 */}
GOFLIX
</h1>
</Link>
</div>
</header>
영화 카드 컴포넌트 패턴
function MovieCard({ movie }) {
return (
<div className="group relative rounded-lg overflow-hidden cursor-pointer
transition-transform duration-300 hover:scale-105
shadow-lg hover:shadow-yellow-400/30">
{/* 포스터 이미지 */}
<img
src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
alt={movie.title}
className="w-full aspect-[2/3] object-cover"
/>
{/* 호버 오버레이 */}
<div className="absolute inset-0 bg-black/70 opacity-0 group-hover:opacity-100
transition-opacity duration-300 flex flex-col justify-end p-4">
<h3 className="text-white font-bold text-sm line-clamp-2">{movie.title}</h3>
<p className="text-yellow-300 text-xs mt-1">⭐ {movie.vote_average.toFixed(1)}</p>
</div>
</div>
);
}
전체 페이지 레이아웃
// App.jsx
<main className="bg-black text-white min-h-screen pt-16">
{/* bg-black: 검은 배경 */}
{/* text-white: 기본 텍스트 흰색 */}
{/* min-h-screen: 최소 전체 높이 */}
{/* pt-16: 상단 64px (fixed 헤더 높이만큼) */}
<Outlet />
</main>
// 홈 페이지
<section className="container mx-auto px-4 py-8">
<h2 className="text-2xl font-bold mb-6 text-yellow-300">인기 영화</h2>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
{movies.map(movie => <MovieCard key={movie.id} movie={movie} />)}
</div>
</section>
버튼 스타일 패턴
{/* 주요 액션 버튼 */}
<button className="bg-yellow-400 text-black font-bold px-6 py-2 rounded-lg
hover:bg-yellow-300 active:scale-95
transition-all duration-200 cursor-pointer">
자세히 보기
</button>
{/* 보조 버튼 (아웃라인) */}
<button className="border-2 border-white text-white font-semibold px-6 py-2 rounded-lg
hover:bg-white hover:text-black
transition-all duration-200 cursor-pointer">
목록 추가
</button>
영화 상세 페이지
function MovieDetail({ movie }) {
return (
<div className="relative min-h-screen bg-black text-white">
{/* 배경 이미지 */}
<div className="relative h-[60vh]">
<img
src={`https://image.tmdb.org/t/p/original${movie.backdrop_path}`}
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent" />
</div>
{/* 콘텐츠 */}
<div className="container mx-auto px-4 -mt-32 relative z-10">
<div className="flex flex-col md:flex-row gap-8">
<img
src={`https://image.tmdb.org/t/p/w300${movie.poster_path}`}
className="w-40 md:w-56 rounded-xl shadow-2xl flex-none mx-auto md:mx-0"
/>
<div className="flex-1">
<h1 className="text-3xl md:text-5xl font-black">{movie.title}</h1>
<div className="flex items-center gap-3 mt-3 text-sm text-gray-400">
<span className="text-yellow-400 font-bold">⭐ {movie.vote_average.toFixed(1)}</span>
<span>{movie.release_date.slice(0, 4)}</span>
</div>
<p className="mt-4 text-gray-300 leading-relaxed max-w-2xl line-clamp-4 md:line-clamp-none">
{movie.overview}
</p>
<div className="flex gap-3 mt-6">
<button className="bg-yellow-400 text-black font-bold px-6 py-3 rounded-lg
hover:bg-yellow-300 active:scale-95 transition-all duration-200">
▶ 재생
</button>
<button className="border border-white/40 text-white px-6 py-3 rounded-lg
hover:bg-white/10 transition-all duration-200">
+ 내 목록
</button>
</div>
</div>
</div>
</div>
</div>
)
}
요약
클래스 조합 팁
복잡한 컴포넌트는 관심사별로 줄을 나눠 읽기 좋게 작성한다.
레이아웃 → 크기 → 색상 → 상태 순으로 배치하면 유지보수가 편하다.
주의
자주 하는 실수
hover:scale-105만 쓰면 애니메이션이 없음 →transition-transform duration-300필수opacity-0 group-hover:opacity-100을 쓸 때 부모에group클래스 빠뜨리지 않기fixed헤더가 있으면 main에pt-{헤더높이}필수 (겹침 방지)
// 1단계: bg-color — 단색 배경
<div className="bg-black">검은 배경</div>
<div className="bg-gray-800">어두운 회색 배경</div>
<div className="bg-yellow-400">노란 배경</div>
// 2단계: bg-color + text-color — 배경과 텍스트 색상 함께
<div className="bg-gray-900 text-white">어두운 배경에 흰 텍스트</div>
<div className="bg-yellow-400 text-black">노란 배경에 검은 텍스트</div>
// 3단계: bg-color/투명도 — 슬래시로 불투명도 조절
<div className="bg-black/50">50% 투명한 검은 배경</div>
<div className="bg-black/90">90% 불투명한 검은 배경</div>
// 4단계: bg-gradient — 그라디언트 배경
<div className="bg-gradient-to-r from-black to-gray-800">좌 → 우</div>
<div className="bg-gradient-to-t from-black to-transparent">아래 → 위(투명)</div>
1.5. Borders — 테두리 & Ring
1.5.1. Border Width · Color · Style
/* 두께 */
border /* 1px */
border-0 /* 0px */
border-2 /* 2px */
border-4 /* 4px */
border-8 /* 8px */
border-t-2 /* 위만 2px */
border-b /* 아래만 1px */
/* 스타일 */
border-solid border-dashed border-dotted border-none
1.5.2. Border Radius
| 클래스 | 값 |
|---|---|
rounded-none | 0 |
rounded-sm | 2px |
rounded | 4px |
rounded-md | 6px |
rounded-lg | 8px |
rounded-xl | 12px |
rounded-2xl | 16px |
rounded-3xl | 24px |
rounded-full | 9999px (원형) |
1.5.3. Ring (포커스 외곽선)
ring /* 3px outline */
ring-2 /* 2px */
ring-4 /* 4px */
ring-yellow-400 /* 링 색상 */
ring-offset-2 /* 링과 요소 사이 간격 */
// 1단계: border — 기본 테두리
<div className="border">1px 테두리</div>
<div className="border-2">2px 테두리</div>
<div className="border-4">4px 테두리</div>
// 2단계: border-color — 테두리 색상
<div className="border border-gray-600">회색 테두리</div>
<div className="border border-yellow-400">노란 테두리</div>
// 3단계: rounded — 모서리 둥글게
<div className="border rounded">살짝 둥근 (4px)</div>
<div className="border rounded-lg">더 둥근 (8px)</div>
<div className="border rounded-full">완전 원형</div>
// 4단계: 방향별 테두리
<div className="border-t border-gray-700">위쪽만 테두리</div>
<div className="border-b border-gray-700">아래쪽만 테두리</div>
// 5단계: ring — 포커스 외곽선
<button className="ring-2 ring-yellow-400">링 외곽선</button>
<button className="ring-2 ring-yellow-400 ring-offset-2">간격 있는 링</button>
1.6. Layout — 레이아웃 (Display · Position)
1.6.1. Display
| 클래스 | CSS | 설명 |
|---|---|---|
block | display: block | 블록 요소 |
inline | display: inline | 인라인 요소 |
inline-block | display: inline-block | 인라인 블록 |
flex | display: flex | 플렉스 컨테이너 |
inline-flex | display: inline-flex | 인라인 플렉스 |
grid | display: grid | 그리드 컨테이너 |
hidden | display: none | 숨김 |
<div className="block">block — 한 줄 전체를 차지</div>
<span className="inline">inline — 내용 크기만큼, 줄바꿈 없음</span>
<span className="inline-block">inline-block — 줄바꿈 없이 나란히</span>
<div className="hidden">hidden — 화면에서 완전히 사라짐</div>
1.6.2. Position
| 클래스 | CSS |
|---|---|
static | position: static |
relative | position: relative |
absolute | position: absolute |
fixed | position: fixed |
sticky | position: sticky |
1.6.3. 위치 지정 (inset)
| 클래스 | 의미 |
|---|---|
top-0 | 위에서 0 |
left-0 | 왼쪽에서 0 |
inset-0 | 상하좌우 모두 0 |
inset-x-0 | 좌우만 0 |
inset-y-0 | 상하만 0 |
// 1단계: relative — 자식의 기준점 역할
<div className="relative">
기준이 되는 부모
</div>
// 2단계: absolute + top/left — 부모 기준으로 위치 지정
<div className="relative">
<div className="absolute top-0 left-0">왼쪽 위에 배치</div>
<div className="absolute top-0 right-0">오른쪽 위에 배치</div>
</div>
// 3단계: inset-0 — 부모 전체를 꽉 채움
<div className="relative">
<div className="absolute inset-0">부모 전체 크기로 채움</div>
</div>
// 4단계: fixed — 스크롤해도 화면에 고정
<header className="fixed top-0 left-0">스크롤해도 고정되는 헤더</header>
// 5단계: sticky — 스크롤 시 특정 위치에 달라붙음
<h2 className="sticky top-0">스크롤하면 상단에 고정되는 제목</h2>
1.6.4. z-index
// 숫자가 클수록 위에 표시됨
<div className="z-0">맨 아래</div>
<div className="z-10">그 위</div>
<div className="z-50">가장 위</div>
1.7. Flexbox
가장 많이 쓰는 레이아웃 방식. 방향, 줄바꿈, 자식 크기를 클래스 조합으로 제어한다.
1.7.1. 방향 (flex-direction)
| 클래스 | CSS |
|---|---|
flex-row | flex-direction: row (기본값) |
flex-row-reverse | flex-direction: row-reverse |
flex-col | flex-direction: column |
flex-col-reverse | flex-direction: column-reverse |
1.7.2. 줄바꿈 · 자식 크기
/* 줄바꿈 */
flex-wrap flex-nowrap flex-wrap-reverse
/* 자식 요소 크기 제어 */
flex-1 /* flex: 1 1 0% — 공간을 균등 분할 */
flex-auto /* flex: 1 1 auto */
flex-none /* flex: none — 크기 고정 */
/* 개별 크기 */
grow /* flex-grow: 1 */
grow-0 /* flex-grow: 0 */
shrink /* flex-shrink: 1 */
shrink-0 /* flex-shrink: 0 */
// 1단계: flex — 자식을 가로로 나열
<div className="flex">
<div>아이템 1</div>
<div>아이템 2</div>
<div>아이템 3</div>
</div>
// 2단계: flex-col — 세로로 나열
<div className="flex flex-col">
<div>위</div>
<div>중간</div>
<div>아래</div>
</div>
// 3단계: gap — 자식 사이 간격
<div className="flex gap-4">
<div>아이템 1</div>
<div>아이템 2</div>
<div>아이템 3</div>
</div>
// 4단계: flex-1 / flex-none — 자식 크기 제어
<div className="flex">
<div className="flex-none">고정 크기</div>
<div className="flex-1">남은 공간을 모두 차지</div>
</div>
// 5단계: flex-wrap — 넘치면 줄바꿈
<div className="flex flex-wrap gap-2">
<div>태그 1</div>
<div>태그 2</div>
<div>태그 3</div>
<div>태그 4</div>
<div>태그 5</div>
</div>
1.7.3. Container
container는 화면 크기에 따라 max-width를 자동으로 맞춰주는 클래스다. 단독으로는 왼쪽 정렬이므로, mx-auto를 함께 써서 가운데 정렬한다.
| 브레이크포인트 | 적용되는 max-width |
|---|---|
| 기본 (모바일) | 100% |
| sm (640px~) | 640px |
| md (768px~) | 768px |
| lg (1024px~) | 1024px |
| xl (1280px~) | 1280px |
| 2xl (1536px~) | 1536px |
// 1단계: container 기본 — 반응형 max-width 자동 적용
<div className="container">콘텐츠</div>
// 2단계: mx-auto 추가 — 가운데 정렬
<div className="container mx-auto">콘텐츠</div>
// 3단계: 실전 — 페이지 전체 레이아웃에 적용
<main>
<section className="container mx-auto">
<h2>인기 영화</h2>
...
</section>
<section className="container mx-auto">
<h2>최신 영화</h2>
...
</section>
</main>
1.8. Grid
2차원 레이아웃. 영화 카드 목록처럼 열을 고정하거나 반응형으로 배치할 때 사용한다.
1.8.1. 열(Column) 정의
| 클래스 | CSS |
|---|---|
grid-cols-1 | grid-template-columns: repeat(1, 1fr) |
grid-cols-2 ~ 12 | 2~12 등분 |
grid-cols-none | 컬럼 정의 없음 |
grid-cols-[200px_1fr] | 임의값 지정 |
1.8.2. 간격
gap-4 /* row-gap + column-gap: 1rem */
gap-x-6 /* column-gap: 1.5rem */
gap-y-4 /* row-gap: 1rem */
1.8.3. 자식 요소 병합 (span)
col-span-2 /* 열 2칸 차지 */
col-span-full /* 전체 열 차지 */
row-span-2 /* 행 2칸 차지 */
// 1단계: grid + grid-cols — 열 개수 지정
<div className="grid grid-cols-3">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
// 2단계: gap — 셀 사이 간격 추가
<div className="grid grid-cols-3 gap-4">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
// 3단계: col-span — 특정 셀이 여러 칸을 차지
<div className="grid grid-cols-3 gap-4">
<div className="col-span-2">넓은 셀 (2칸)</div>
<div>1칸</div>
<div>1칸</div>
<div className="col-span-full">전체 너비 셀</div>
</div>
// 4단계: 반응형 — 화면 크기에 따라 열 수 변경
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{movies.map(movie => (
<MovieCard key={movie.id} movie={movie} />
))}
</div>
1.9. Alignment — 정렬 (Justify · Align)
Flexbox와 Grid에서 아이템을 정렬하는 유틸리티이다.
1.9.1. 주축 정렬 (justify-content)
| 클래스 | CSS |
|---|---|
justify-start | justify-content: flex-start |
justify-center | justify-content: center |
justify-end | justify-content: flex-end |
justify-between | justify-content: space-between |
justify-around | justify-content: space-around |
justify-evenly | justify-content: space-evenly |
1.9.2. 교차축 정렬 (align-items)
| 클래스 | CSS |
|---|---|
items-start | align-items: flex-start |
items-center | align-items: center |
items-end | align-items: flex-end |
items-stretch | align-items: stretch |
items-baseline | align-items: baseline |
1.9.3. Grid 정렬
place-items-center /* align-items + justify-items: center */
place-content-center
// 1단계: justify-center — 가로 중앙 정렬
<div className="flex justify-center">
<div>가운데 배치됨</div>
</div>
// 2단계: justify-between — 양 끝으로 배치
<div className="flex justify-between">
<div>왼쪽</div>
<div>오른쪽</div>
</div>
// 3단계: items-center — 세로 중앙 정렬
<div className="flex items-center">
<div>세로 중앙에 배치됨</div>
</div>
// 4단계: justify + items 조합 — 완전 중앙
<div className="flex justify-center items-center">
<div>정중앙에 배치됨</div>
</div>
// 5단계: place-items-center — grid에서 셀 안 정중앙
<div className="grid grid-cols-3 place-items-center">
<div>★</div>
<div>★</div>
<div>★</div>
</div>
1.10. Spacing — 간격 (Margin · Padding · Gap)
기본 단위: 1 = 4px (0.25rem). 4 = 16px, 8 = 32px처럼 4배수로 계산한다.
1.10.1. Margin
| 클래스 | 방향 | 예시 |
|---|---|---|
m-{n} | 전체 | m-4 → 16px 사방 |
mx-{n} | 좌우 | mx-auto → 가운데 정렬 |
my-{n} | 상하 | my-8 |
mt-{n} | 위 | mt-16 |
mr-{n} | 오른쪽 | |
mb-{n} | 아래 | |
ml-{n} | 왼쪽 | |
-m-{n} | 음수 마진 | -mt-4 |
1.10.2. Padding (같은 패턴)
p-4 px-6 py-3 pt-2 pr-4 pb-6 pl-2
1.10.3. 자주 쓰는 값 참고표
| 클래스 숫자 | rem | px |
|---|---|---|
| 1 | 0.25rem | 4px |
| 2 | 0.5rem | 8px |
| 3 | 0.75rem | 12px |
| 4 | 1rem | 16px |
| 5 | 1.25rem | 20px |
| 6 | 1.5rem | 24px |
| 8 | 2rem | 32px |
| 10 | 2.5rem | 40px |
| 12 | 3rem | 48px |
| 16 | 4rem | 64px |
| 20 | 5rem | 80px |
| 24 | 6rem | 96px |
// 1단계: p — 사방 패딩
<div className="p-4">사방 16px 여백</div>
<div className="p-8">사방 32px 여백</div>
// 2단계: px / py — 방향별 패딩
<div className="px-6">좌우만 24px</div>
<div className="py-3">상하만 12px</div>
<div className="px-6 py-3">좌우 24px + 상하 12px</div>
// 3단계: mt / mb — 위아래 마진
<div className="mt-8">위에 32px 여백</div>
<div className="mb-4">아래에 16px 여백</div>
// 4단계: mx-auto — 가운데 정렬
<div className="mx-auto">가운데 정렬</div>
// 5단계: space-y — 자식 요소 사이 세로 간격
<div className="space-y-4">
<div>첫 번째 항목</div>
<div>두 번째 항목</div>
<div>세 번째 항목</div>
</div>
1.11. Effects — 그림자 & 불투명도
1.11.1. Box Shadow
shadow-sm /* 작은 그림자 */
shadow /* 기본 그림자 */
shadow-md /* 중간 그림자 */
shadow-lg /* 큰 그림자 */
shadow-xl /* 더 큰 그림자 */
shadow-2xl /* 가장 큰 그림자 */
shadow-none /* 그림자 제거 */
/* 색상 그림자 */
shadow-lg shadow-black/50
1.11.2. Opacity (불투명도)
opacity-0 /* 완전 투명 */
opacity-50 /* 반투명 */
opacity-100 /* 불투명 */
// 1단계: shadow — 그림자 크기
<div className="shadow">기본 그림자</div>
<div className="shadow-md">중간 그림자</div>
<div className="shadow-xl">큰 그림자</div>
// 2단계: shadow-color — 색상 그림자
<div className="shadow-lg shadow-black/50">검은 그림자</div>
<div className="shadow-lg shadow-yellow-400/30">노란 그림자</div>
// 3단계: opacity — 요소 전체 투명도
<div className="opacity-100">완전 불투명</div>
<div className="opacity-50">반투명</div>
<div className="opacity-0">완전 투명 (공간은 차지)</div>
1.12. Filters — 필터 (Blur · Backdrop)
blur-none blur-sm blur blur-md blur-lg blur-xl
/* 배경 블러 (유리 효과) */
backdrop-blur-sm backdrop-blur-md backdrop-blur-lg
// 1단계: blur — 요소 자체를 흐리게
<img className="blur-none" src={img} alt="" />
<img className="blur-sm" src={img} alt="" />
<img className="blur-lg" src={img} alt="" />
// 2단계: backdrop-blur — 요소 뒤 배경을 흐리게
<div className="backdrop-blur-sm">약하게 흐린 배경</div>
<div className="backdrop-blur-md">중간 흐린 배경</div>
<div className="backdrop-blur-lg">많이 흐린 배경</div>
// 3단계: backdrop-blur + bg-*/투명도 — 유리 효과
<div className="backdrop-blur-md bg-white/10">유리처럼 반투명한 카드</div>
1.13. Transitions & Animation — 트랜지션
transition /* all 속성 */
transition-colors /* 색상만 */
transition-transform
transition-opacity
duration-150 /* 150ms */
duration-300 /* 300ms */
ease-in ease-out ease-in-out
// 1단계: transition — 변화를 부드럽게 (hover와 함께)
<div className="transition hover:opacity-50">호버 시 서서히 반투명</div>
// 2단계: duration — 애니메이션 시간
<div className="transition duration-150 hover:opacity-50">빠름 (150ms)</div>
<div className="transition duration-500 hover:opacity-50">느림 (500ms)</div>
// 3단계: transition-colors — 색상만 전환
<div className="transition-colors duration-200 hover:bg-yellow-400">
호버 시 배경색만 전환
</div>
// 4단계: transition-transform — 크기·위치 전환
<div className="transition-transform duration-300 hover:scale-105">
호버 시 크기만 전환
</div>
// 5단계: ease — 가속도 곡선
<div className="transition duration-300 ease-in hover:opacity-0">천천히 시작</div>
<div className="transition duration-300 ease-out hover:opacity-0">천천히 끝</div>
<div className="transition duration-300 ease-in-out hover:opacity-0">양쪽 천천히</div>
1.14. Transforms — 변형
scale-95 scale-100 scale-105 scale-110
-translate-y-1 translate-x-2
rotate-45 rotate-90 rotate-180
// 1단계: scale — 크기 변형
<div className="scale-75">75% 축소</div>
<div className="scale-100">기본 크기</div>
<div className="scale-110">110% 확대</div>
// 2단계: translate — 위치 이동 (공간은 유지)
<div className="translate-x-4">오른쪽으로 16px</div>
<div className="-translate-y-2">위로 8px</div>
// 3단계: rotate — 회전
<div className="rotate-45">45도 회전</div>
<div className="rotate-90">90도 회전</div>
<div className="rotate-180">180도 회전</div>
// 4단계: transition + transform — 부드러운 변형
<div className="transition-transform duration-300 hover:scale-110">
호버 시 서서히 확대
</div>
<div className="transition-transform duration-300 hover:-translate-y-1">
호버 시 서서히 위로 이동
</div>
1.15. Interactivity — 상호작용 (State Variants · Cursor)
1.15.1. Cursor
cursor-pointer cursor-default cursor-not-allowed cursor-wait
1.15.2. 주요 State Variants
클래스 앞에 상태:를 붙이면 해당 상태일 때만 적용된다.
| Variant | 설명 | 예시 |
|---|---|---|
hover: | 마우스 올림 | hover:bg-yellow-400 |
focus: | 포커스 | focus:ring-2 |
active: | 클릭 중 | active:scale-95 |
disabled: | 비활성화 | disabled:opacity-50 |
checked: | 체크됨 | checked:bg-blue-600 |
group-hover: | 부모 hover 시 | group-hover:opacity-100 |
peer-focus: | 형제 포커스 시 | peer-focus:text-blue-500 |
first: | 첫 번째 자식 | first:mt-0 |
last: | 마지막 자식 | last:mb-0 |
odd: / even: | 홀수/짝수 | odd:bg-gray-50 |
// 1단계: hover: — 마우스를 올렸을 때
<div className="hover:opacity-50">호버 시 반투명</div>
<div className="hover:bg-yellow-400">호버 시 노란 배경</div>
// 2단계: focus: — 포커스 받았을 때 (입력 필드 등)
<input className="focus:outline-none" />
<input className="focus:ring-2 focus:ring-yellow-400" />
// 3단계: active: — 클릭하는 순간
<button className="active:scale-95">클릭 시 줄어듦</button>
<button className="active:opacity-70">클릭 시 반투명</button>
// 4단계: disabled: — 비활성화 상태
<button disabled className="disabled:opacity-50">비활성 (흐리게)</button>
<button disabled className="disabled:cursor-not-allowed">비활성 (커서 금지)</button>
// 5단계: group-hover: — 부모에 hover 시 자식에 적용
<div className="group">
<p className="group-hover:text-yellow-400">부모에 호버하면 색상 변경</p>
</div>
// 부모 hover 시 숨겨진 오버레이 표시
<div className="group relative">
<img src={poster} />
<div className="absolute inset-0 opacity-0 group-hover:opacity-100">
오버레이
</div>
</div>
// 6단계: odd: / even: — 홀짝 번째 스타일
<ul>
<li className="odd:bg-gray-900 even:bg-gray-800">항목 1 (홀수 → 어두운)</li>
<li className="odd:bg-gray-900 even:bg-gray-800">항목 2 (짝수 → 밝은)</li>
<li className="odd:bg-gray-900 even:bg-gray-800">항목 3 (홀수 → 어두운)</li>
</ul>
1.16. 반응형 (Breakpoint)
Tailwind는 모바일 퍼스트이다. 기본값이 모바일이고, 접두사로 더 큰 화면을 지정한다.
1.16.1. 기본 브레이크포인트
| 접두사 | 최소 너비 | 기기 |
|---|---|---|
| (없음) | 0px~ | 모바일 (기본) |
sm: | 640px~ | 소형 태블릿 |
md: | 768px~ | 태블릿 |
lg: | 1024px~ | 노트북 |
xl: | 1280px~ | 데스크탑 |
2xl: | 1536px~ | 대형 모니터 |
// 1단계: 브레이크포인트 하나 — md 이상에서 적용
<p className="text-sm md:text-xl">md 이상에서 커짐</p>
// 2단계: 브레이크포인트 두 개 — 단계적으로 변경
<p className="text-sm md:text-lg lg:text-2xl">화면이 커질수록 텍스트도 커짐</p>
// 3단계: hidden / block 조합 — 특정 화면에서 보이기/숨기기
<div className="hidden md:block">md 이상에서만 보임</div>
<div className="block md:hidden">md 미만에서만 보임 (모바일 전용)</div>
// 4단계: flex-col → flex-row — 모바일: 세로, 데스크탑: 가로
<div className="flex flex-col md:flex-row">
<div>첫 번째</div>
<div>두 번째</div>
</div>
// 5단계: grid-cols 반응형 — 화면 크기에 따라 열 수 변경
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div>카드 1</div>
<div>카드 2</div>
<div>카드 3</div>
<div>카드 4</div>
</div>
1.17. Dark Mode
1.17.1. 설정 (media 모드 — OS 자동)
// OS 다크모드 설정에 따라 자동 전환
<div className="bg-white dark:bg-gray-900">
라이트: 흰 배경 / 다크: 어두운 배경
</div>
1.17.2. 수동 토글 방식 (class 모드)
/* src/index.css */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
// HTML 루트에 dark 클래스 추가/제거로 제어
document.documentElement.classList.toggle('dark')
// 1단계: dark: 텍스트 색상
<p className="text-black dark:text-white">라이트: 검은색 / 다크: 흰색</p>
<p className="text-gray-700 dark:text-gray-300">라이트: 진한 회색 / 다크: 밝은 회색</p>
// 2단계: dark: 배경 색상
<div className="bg-white dark:bg-gray-900">라이트: 흰 배경 / 다크: 어두운 배경</div>
<div className="bg-gray-100 dark:bg-gray-800">라이트: 밝은 회색 / 다크: 짙은 회색</div>
// 3단계: 텍스트 + 배경 조합
<div className="bg-white dark:bg-gray-900 text-black dark:text-white">
다크모드 대응 카드
</div>
// 4단계: 토글 버튼으로 직접 제어
function DarkToggle() {
const [dark, setDark] = useState(false)
const toggle = () => {
setDark(prev => !prev)
document.documentElement.classList.toggle('dark')
}
return (
<button onClick={toggle}>
{dark ? '🌙 다크' : '☀️ 라이트'}
</button>
)
}
요약
클래스 조합 팁
복잡한 컴포넌트는 관심사별로 줄을 나눠 읽기 좋게 작성한다.
레이아웃 → 크기 → 색상 → 상태 순으로 배치하면 유지보수가 편하다.
주의
자주 하는 실수
hover:scale-105만 쓰면 애니메이션이 없음 →transition-transform duration-300필수opacity-0 group-hover:opacity-100을 쓸 때 부모에group클래스 빠뜨리지 않기fixed헤더가 있으면 main에pt-{헤더높이}필수 (겹침 방지)