From clean-tailwind
Use when refactoring Tailwind CSS class order in React/Next.js components, when className strings feel disorganized, or when establishing consistent CSS ordering conventions across a codebase
npx claudepluginhub window-ook/claude-code-lab --plugin clean-tailwindThis skill uses the workspace's default tool permissions.
Tailwind CSS 클래스를 일관된 순서로 정렬하는 기법입니다. **핵심 원칙**: 시각적 렌더링 순서(바깥→안쪽→콘텐츠)를 따릅니다.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Reviews prose for communication issues impeding comprehension, outputs minimal fixes in a three-column table per Microsoft Writing Style Guide. Useful for 'review prose' or 'improve prose' requests.
Tailwind CSS 클래스를 일관된 순서로 정렬하는 기법입니다. 핵심 원칙: 시각적 렌더링 순서(바깥→안쪽→콘텐츠)를 따릅니다.
Use when:
className 문자열이 길고 무질서해 보일 때Don't use for:
| 순위 | 카테고리 | 속성 |
|---|---|---|
| 0 | 커스텀 CSS | card-tilt, hover-button 등 프로젝트 커스텀 클래스 (맨 앞) |
| 1 | 포지션 | absolute, relative, fixed, sticky, static, inset-*, top-*, right-*, bottom-*, left-*, z-* |
| 2 | 레이아웃 | w-*, h-*, size-*, min-w-*, max-w-*, min-h-*, max-h-*, overflow-*, aspect-*, container, block, inline-*, hidden, visible, invisible |
| 3 | 공백 | m-*, mx-*, my-*, mt-*, mr-*, mb-*, ml-*, p-*, px-*, py-*, pt-*, pr-*, pb-*, pl-*, gap-*, gap-x-*, gap-y-*, space-x-*, space-y-* |
| 4 | 외곽 효과 | border-*, rounded-*, shadow-*, ring-*, outline-*, divide-* |
| 5 | 배경색 | bg-*, opacity-*, backdrop-*, gradient-*, from-*, via-*, to-* |
| 6 | Flex/Grid | flex, flex-row, flex-col, flex-wrap, flex-1, grow, shrink, basis-*, grid, grid-cols-*, grid-rows-*, col-span-*, row-span-*, justify-*, items-*, self-*, place-*, order-* |
| 7 | 폰트 | text-*, font-*, leading-*, tracking-*, whitespace-*, truncate, line-clamp-*, break-*, underline, line-through, no-underline, uppercase, lowercase, capitalize, italic, not-italic, list-*, indent-* |
| 8 | 애니메이션 | animate-* |
| 9 | 트랜지션 | transition-*, duration-*, ease-*, delay-* |
| - | 인터랙션 | cursor-*, pointer-events-*, select-*, touch-*, scroll-*, snap-*, will-change-* — 해당 속성 바로 뒤에 배치 (hover:/focus:와 동일 위치) |
| - | 조건부 | hover:, focus:, active:, disabled:, group-hover:, peer-*: — 해당 기본 클래스 바로 뒤에 배치 |
| - | 반응형 | sm:, md:, lg:, xl:, 2xl: — 해당 기본 클래스 바로 뒤에 배치 |
// ❌ Before: 무질서한 순서
className =
'px-4 hover:bg-blue-600 py-2 bg-blue-500 text-white rounded-lg font-bold';
// ✅ After: 정렬된 순서 (외곽→배경→공백→폰트)
className =
'rounded-lg bg-blue-500 hover:bg-blue-600 px-4 py-2 font-bold text-white';
조건부 클래스(hover:, focus:, disabled:)는 해당 기본 클래스 바로 뒤에 배치:
// ✅ 올바름: bg-blue-500 바로 뒤에 hover:bg-blue-600
className = 'rounded-lg bg-blue-500 hover:bg-blue-600 px-4 py-2';
// ❌ 잘못됨: hover가 bg와 분리됨
className = 'rounded-lg bg-blue-500 px-4 py-2 hover:bg-blue-600';
// ❌ Before
className = 'w-8 h-8';
// ✅ After
className = 'size-8';
동적 클래스가 포함된 경우, 정적 부분만 정렬하고 동적 부분은 원래 위치 유지:
// 동적 클래스 (${cardColor})는 해당 카테고리 위치에 배치
className={`card-tilt size-full p-4 border-6 ${cardColorByGrade} rounded-2xl flex flex-col`}
// 커스텀 레이아웃 공백 외곽 동적(외곽/배경) 외곽 Flex
조건부 스타일 객체는 순서 변경 없이 유지:
className={cn(
"rounded-lg bg-white px-4 py-2", // 정적 부분만 정렬
isDarkMode && "bg-gray-800", // 조건부는 그대로
isActive && "ring-2 ring-blue-500" // 조건부는 그대로
)}
| 실수 | 수정 |
|---|---|
| 공백이 외곽보다 먼저 | px-4 rounded-lg → rounded-lg px-4 |
| 포지션이 레이아웃 뒤에 | w-full relative → relative w-full |
| 조건부가 기본 클래스와 분리됨 | 기본 클래스 바로 뒤로 이동 |
| w-8 h-8 중복 | size-8로 통합 |
대규모 리팩토링 시 권장 워크플로우:
git checkout -b refactor/tailwind-class-order작업 시 주의 신호: