Tailwind CSS를 처음 쓰면 누구나 한 번쯤 겪는 문제입니다. (내 얘기…)
방금 겪은 문제 상황
const ORANGE = "#FF5733";
const ORANGE_CLASS= "text-[#FF5733]"
// ❌ 색상이 안 나옴!
<span className={`text-[${ORANGE}]`}>Chat</span>
// ⭕ 색상이 자잘 나옴
<span className={ORANGE_CLASS}>Chat</span>
분명히 Tailwind 문서에는 text-[#FF5733] 이렇게 쓰면 된다고 했는데…
왜 변수를 넣으면 안 될까요?
결론부터 말하면
Tailwind은 코드를 “실행”하지 않고 “텍스트로 읽기”만 합니다.
변수 ${ORANGE}가 #FF5733으로 바뀌는 건 JavaScript가 실행될 때인데,
Tailwind은 그 전에 이미 CSS를 만들어버립니다.
실제로 무슨 일이 일어날까?
npm run dev로 개발 서버를 실행하고 파일을 저장하면:
(1) PostCSS (Tailwind CSS) 처리를 먼저 진행한 후
(2) Babel (Javascript Compiler)이 변수, 템플릿 리터럴 (`)을 처리함
~> 변수를 문자열로 바꾸는 (2)번이 실행 되기 전에
(1) Tailwind CSS 처리하는 로직이 작동되기 때문에
해석이 안 되어서 색상 코드 적용이 안 됨
1단계: Tailwind이 파일을 스캔
파일 내용: className={`text-[${ORANGE}]`}
↑
Tailwind: "이게 뭐지? 색상코드 아닌데... 무시!"
2단계: CSS 생성
/* text-[#FF5733]에 대한 CSS가 안 만들어짐! */
3단계: JavaScript 실행 (브라우저)
${ORANGE} → #FF5733 으로 변환됨
결과: class="text-[#FF5733]"
4단계: 브라우저가 스타일 적용 시도
브라우저: "text-[#FF5733] 클래스의 CSS 어딨지?"
→ 없음!
→ 스타일 적용 안 됨 ❌
시간 순서가 핵심!
| 순서 | 단계 | 상태 |
|---|---|---|
| 1 | Tailwind 스캔 | ${ORANGE} (아직 변수 그대로) |
| 2 | CSS 생성 | 해당 클래스 없음 |
| 3 | JS 실행 | #FF5733으로 변환됨 |
| 4 | 브라우저 | CSS 없어서 적용 불가 ❌ |
Tailwind이 먼저, JavaScript가 나중!
순서가 맞지 않아서 문제가 생깁니다.
왜 Tailwind이 먼저 실행될까?
Next.js 빌드 파이프라인 순서 때문입니다:
1. PostCSS (Tailwind 포함)
→ CSS 파일들 처리
→ 소스코드 스캔해서 클래스 수집
→ 최종 CSS 생성
↓
2. Babel / SWC (JavaScript 컴파일러)
→ JSX → JavaScript 변환
→ 변수, 템플릿 리터럴 처리
↓
3. 번들링 (Webpack / Turbopack)
→ 모든 파일 합치기
CSS는 JavaScript 실행 결과를 몰라도 만들 수 있어야 하고,
미리 만들어놔야 페이지 로딩이 빠르기 때문에 이 순서로 동작합니다.
해결 방법
방법 1: 그냥 직접 쓰기
// 가장 간단한 방법
<span className="text-[#FF5733]">Chat</span>
방법 2: 인라인 스타일 사용
const ORANGE = "#FF5733";
<span style={{ color: ORANGE }}>Chat</span>
방법 3: 전체 클래스를 변수에 저장
// 전체 문자열이 코드에 보이면 OK
const orangeText = "text-[#FF5733]";
<span className={orangeText}>Chat</span>
방법 4: Tailwind 기본 색상 사용
<span className="text-orange-500">Chat</span>
이것도 안 됩니다!
// ❌ 클래스 이름 조합
const color = "red";
<div className={`bg-${color}-500`} />
// ❌ 조건부 클래스 조합
const size = "lg";
<div className={`text-${size}`} />
Tailwind은 bg-red-500, text-lg라는 완전한 문자열을 봐야 합니다.
조건부 스타일은 이렇게!
// ✅ 전체 클래스를 조건부로 선택
<div className={isActive ? "bg-red-500" : "bg-gray-500"} />
// ✅ 객체로 매핑
const colors = {
red: "bg-red-500",
blue: "bg-blue-500",
};
<div className={colors[selectedColor]} />
정리
| 방식 | 작동 여부 |
|---|---|
text-[#FF5733] |
✅ |
`text-[${변수}]` |
❌ |
style={{ color: 변수 }} |
✅ |
조건 ? "클래스A" : "클래스B" |
✅ |
핵심: Tailwind은 텍스트만 읽는다!