2025년 1월 23일, tailwind 4.0 버전이 출시되었습니다. 기존 프로젝트에 3.x 버전을 사용하던 저는 Nextjs 14 -> 15 마이그레이션과 함께 tailwindcss 업그레이드도 결정했습니다. Nextjs 15버전 업그레이드 전, tailwindcss 버전을 먼저 올리고 테스트 후 Nextjs 업그레이드 진행을 추천드립니다.
따라서 이번 포스팅에서는
Tailwind CSS 3.0에서 4.0으로의 마이그레이션
을 공식 문서를 기반으로 완벽하게 정리해드리겠습니다. Tailwind CSS를 사용하고 계시다면, 4.0으로의 전환은 성능과 생산성 측면에서 매우 큰 이점을 제공합니다. 그럼 본격적으로 시작해보겠습니다.
Tailwind CSS v4.0은 최신 브라우저용으로 설계되었으며 사파리 16.4, 크롬 111, 파이어폭스 128을 지원합니다. 이전 브라우저를 위해서는 v3.4를 사용해야 합니다.
Tailwind 팀은 손쉽게 업그레이드할 수 있도록
@tailwindcss/upgrade
CLI를 제공합니다.
진행 전, 커밋되지 않은 변경사항이 있는지 확인하고,
git stash
또는
git commit
으로 안전하게 백업해두세요.
자동으로 다음 항목을 수행합니다
tailwindcss 버전 업데이트
tailwind.config.js 제거 또는 변환
postcss.config.js 변환
템플릿 파일 내 클래스 정리
필요한 경우 설정을 theme API 기반으로 변경
upgrade tool
이 자동으로 업그레이드를 해주었지만, 새로운 사용법과 변경 사항을 이해하고 있어야 하겠죠. 그래서 Tailwind CSS 4.0에서 변경된 사항을 정리해보았습니다.
✅
@tailwind directives 제거 🔗
기존 tailwind에서는 css 파일에 @tailwind 지시문을 사용하여 Tailwind CSS를 가져왔습니다. 하지만 v4에서는 @tailwind 지시문이 제거되었습니다. 대신, CSS 파일에서 직접 Tailwind CSS를 가져와야 합니다.
/* v3 */
/* @tailwind base; */
/* @tailwind components; */
/* @tailwind utilities; */
/* v4 */
@import "tailwindcss" ;
이제 @tailwind 지시문은 더 이상 필요하지 않으며, CSS 파일에서 제거해야 합니다.
v3에서 더 이상 사용되지 않는 모든 유틸리티가 제거되었습니다. 다음은 제거된 유틸리티 목록과 최신 대체 유틸리티입니다.
이전 이후 기능 bg-opacity-* Use opacity modifiers like bg-black/50 배경 불투명도 설정 text-opacity-* Use opacity modifiers like text-black/50 텍스트 불투명도 설정 border-opacity-* Use opacity modifiers like border-black/50 테두리 불투명도 설정 divide-opacity-* Use opacity modifiers like divide-black/50 구분선 불투명도 설정 ring-opacity-* Use opacity modifiers like ring-black/50 링 불투명도 설정 placeholder-opacity-* Use opacity modifiers like placeholder-black/50 플레이스홀더 불투명도 설정 flex-shrink-* shrink-* 플렉스 축소 설정 flex-grow-* grow-* 플렉스 확장 설정 overflow-ellipsis text-ellipsis 오버플로우 생략 설정 decoration-slice box-decoration-slice 박스 장식 슬라이스 설정 decoration-clone box-decoration-clone 박스 장식 복제 설정
v4에서 다음 유틸리티의 이름이 변경되었습니다. 이 변경 사항은 Tailwind CSS v4.0에서만 적용됩니다.
shadow, drop-shadow, blur, backdrop-blur, rounded, outline, ring에서의 변경 사항은 다음과 같습니다
이전 이후 기능 shadow-sm shadow-xs 그림자 크기 설정 shadow shadow-sm 그림자 크기 설정 drop-shadow-sm drop-shadow-xs 드롭 그림자 크기 설정 drop-shadow drop-shadow-sm 드롭 그림자 크기 설정 blur-sm blur-xs 블러 크기 설정 blur blur-sm 블러 크기 설정 backdrop-blur-sm backdrop-blur-xs 백드롭 블러 크기 설정 backdrop-blur backdrop-blur-sm 백드롭 블러 크기 설정 rounded-sm rounded-xs 모서리 반경 크기 설정 rounded rounded-sm 모서리 반경 크기 설정 outline-none outline-hidden 아웃라인 제거 설정 ring ring-3 링 크기 설정
➡️
그림자, 반경, 흐림 스케일 업데이트 🔗
모든 유틸리티에 이름이 지정된 값을 갖도록 기본 shadow, blur 및 rounded 스케일의 이름이 바뀌었습니다. 이전 버전과의 호환성을 위해 여전히 작동하지만, -sm 유틸리티는 -xs 으로 업데이트하지 않으면 모양이 달라집니다.
{/* v3 버전 */}
< input class = "shadow-sm" />
{/* v4 버전 */}
< input class = "shadow-xs" />
{/* v3 버전 */}
< input class = "shadow" />
{/* v4 버전 */}
< input class = "shadow-sm" />
outline
유틸리티가 이제 기본적으로 outline-width: 1px
및 outline-style: solid
를 포함합니다. 이전 버전에서는 outline
유틸리티가 outline-style: solid
만 포함하고 있었습니다. 이제 outline
유틸리티는 기본적으로 outline-width: 1px
및 outline-style: solid
를 포함합니다.
{/* v3 버전 */}
< input class = "outline outline-2" />
{/* v4 버전 */}
< input class = "outline-2" />
또한 outline-none
은 outline-style: none
을 실제로 적용하지 않아 이름이 outline-hidden
으로 변경되었습니다.
{/* v3 버전 */}
< input class = "focus:outline-none" />
{/* v4 버전 */}
< input class = "focus:outline-hidden" />
ring
유틸리티의 기본 두께가 3px
→ 1px
로 바뀌었습니다.
{/* v3 버전 */}
< input class = "ring ring-blue-500" />
{/* v4 버전 */}
< input class = "ring-3 ring-blue-500" />
➡️
그라디언트와 variant 함께 사용 시 동작 개선 🔗
이제 다크 모드에서도
to-*
설정이 유지되며, 필요 시
via-none
으로 제거해야 합니다.
After:
< div class = "bg-gradient-to-r from-red-500 via-orange-400 to-yellow-400 dark:via-none dark:from-blue-500 dark:to-teal-400" ></ div >
container
의 center, padding 등 설정이 제거되었습니다. 직접 정의해주셔야 합니다.
@utility container {
margin-inline : auto;
padding-inline : 2rem;
}
이제 border-*
, divide-*
는 기본 색상이 currentColor
입니다. gray-200
을 유지하고 싶다면 아래처럼 설정하세요.
@layer base {
* , ::after , ::before , ::backdrop , :: file-selector-button {
border-color : var ( --color-gray-200 , currentColor );
}
}
기본 placeholder 색상은 이제 텍스트 색상의 50% 투명도입니다. 기존 스타일을 유지하려면 다음을 추가하세요:
@layer base {
input ::placeholder ,
textarea ::placeholder {
color : var ( --color-gray-400 );
}
}
버튼의 기본 커서가 pointer
→ default
로 변경되었습니다. 이전 스타일을 유지하려면 다음을 추가하세요:
@layer base {
button :not ( :disabled ),
[ role = "button" ] :not ( :disabled ) {
cursor : pointer ;
}
}
@layer base {
dialog {
margin : auto ;
}
}
➡️
사용자 정의 유틸리티 등록 방식 변경 🔗
@layer utilities
대신 @utility
를 사용합니다.
@utility tab-4 {
tab-size : 4;
}
➡️
variant stacking 방향 변경 🔗
이제 stacked variants는
왼쪽에서 오른쪽으로
해석됩니다.
{/* v3 버전 */}
< ul class = "py-4 first:*:pt-0 last:*:pb-0" >
{/* v4 버전 */}
< ul class = "py-4 *:first:pt-0 *:last:pb-0" >
bg-[--color]
→ bg-(--color)
형태로 변경되었습니다.
< div class = "bg-(--brand-color)" ></ div >
➡️
hover 스타일은 hover 지원 장치에서만 적용 🔗
터치 장치 호환을 위해 커스텀 variant를 등록할 수 있습니다.
@custom-variant hover (&:hover);
➡️
outline-color도 transition 대상에 포함됨 🔗
< button class = "transition hover:outline-2 hover:outline-cyan-500" ></ button >
corePlugins
로 유틸리티 비활성화하는 방식은 지원되지 않습니다.
➡️
theme() 함수 대신 변수 사용 권장 🔗
.my-class {
background-color : var ( --color-red-500 );
}
➡️
4-18. JS 설정 파일은 명시적으로 불러야 함 🔗
@config "../../tailwind.config.js";
➡️
4-19. theme 값의 JavaScript 접근 🔗
이제 resolveConfig
없이도 getComputedStyle
로 변수 값을 가져올 수 있습니다.
let styles = getComputedStyle (document.documentElement);
let shadow = styles. getPropertyValue ( "--shadow-xl" );
@import 'tailwindcss' ;
@theme {
--color-primary: #1da1f2 ;
--font-sans: 'Inter', sans-serif ;
}
@utilities {
.btn {
@ apply px- 4 py- 2 rounded bg-primary text-white ;
}
}
🚀
기능별 Before / After 예시 🔗
// Before (3.x)
theme : {
extend : {
colors : {
brand : '#3490dc' ,
},
},
}
// After (4.x)
@theme {
-- color - brand : #3490dc;
}
{/* Before (3.x) */}
< div class = "text-slate-900/80" ></ div >
{/* After (4.x) */}
< div class = "text-slate-900 text-opacity-80" ></ div >
모든 템플릿 경로에서 스타일이 정상 동작하는지 확인합니다.
npm run build
시 오류나 경고가 없는지 확인합니다.
PostCSS 설정이 잘 반영되었는지 확인합니다.
개발 환경과 배포 환경 양쪽에서 정상 동작하는지 테스트합니다.
Tailwind CSS 4.0은 단순한 버전 업그레이드가 아니라, 설정 구조, 지원 환경, 사용 방식 전반에 걸친
근본적인 리디자인
입니다. 그러나 자동 도구를 활용하거나, 위의 가이드를 참고해 수동으로 하나하나 점검해가면 충분히 안전하고 빠르게 전환할 수 있습니다.
특히 CSS 중심 설정과 최신 브라우저 대응 방식은 앞으로의 웹 개발에 있어 큰 이점이 될 것입니다. 최신 Tailwind를 도입하고자 하는 분들에게 이번 포스팅이 좋은 로드맵이 되길 바랍니다.