왜 BEM 네스팅이 Tailwind v4에서 깨지는가
Source: Dev.to
오늘은 특정 CSS 스타일이 적용되지 않는 이유를 디버깅하는 데 시간을 보냈습니다. Tailwind v4가 Tailwind v3에서 작동하던 것을 조용히 깨뜨린 것으로 드러났습니다.
원본 BEM‑스타일 네스팅
/* BEM nesting */
.dropdown {
background: white;
&--open {
background: blue;
}
&__icon {
width: 16px;
}
}
Tailwind v3에서는 다음과 같이 컴파일되었습니다:
.dropdown { background: white; }
.dropdown--open { background: blue; }
.dropdown__icon { width: 16px; }
Tailwind v4에서는 아무 출력도 없으며—오류도 경고도 없이 조용히 사라집니다.
여전히 작동하는 것
.dropdown {
&:hover { background: gray; }
& .child { color: red; }
}
&:hover는 작동하지만 &--open은 작동하지 않습니다. 이유는 네이티브 CSS 네스팅과 Sass‑스타일 네스팅의 차이에 있습니다.
네이티브 CSS vs. Sass 네스팅
| 기능 | 네이티브 CSS 지원 | Sass 지원 | Tailwind v3 | Tailwind v4 |
|---|---|---|---|---|
&:hover (pseudo‑class) | ✅ | ✅ | 작동 | 작동 |
& .child (combinator) | ✅ | ✅ | 작동 | 작동 |
&.another-class (chaining) | ✅ | ✅ | 작동 | 작동 |
&--modifier (string concat) | ❌ | ✅ | 작동 | 깨짐 |
&__element (string concat) | ❌ | ✅ | 작동 | 깨짐 |
- 네이티브 CSS 네스팅(브라우저가 이해하는 것)은
&를 의사 클래스, 조합자, 간단한 체이닝에만 허용합니다. - Sass는
&를 사용해 문자열을 연결할 수 있는 기능을 추가하여&--open이나&__icon같은 BEM‑스타일 선택자를 만들 수 있게 합니다. 이는 실제 CSS가 아닙니다.
Tailwind v4에서 무엇이 바뀌었나요?
- Tailwind v3은
postcss-nested를 사용했으며, 이는 Sass의 문자열 연결 동작을 흉내냈습니다. - Tailwind v4는 Lightning CSS로 전환했으며, 이는 공식 CSS 네스팅 사양을 따르기 때문에 문자열 연결을 지원하지 않습니다. BEM 네스팅은 조용히 실패합니다.
문제 해결
문자열 연결에 의존하지 말고 전체 클래스 이름을 직접 작성하세요:
/* Before (broken in v4) */
.dropdown {
&--open { background: blue; }
&__icon { width: 16px; }
}
/* After (works everywhere) */
.dropdown--open { background: blue; }
.dropdown__icon { width: 16px; }
네이티브 CSS가 지원하는 부분은 여전히 중첩할 수 있습니다:
.dropdown {
&:hover { background: gray; }
& .dropdown__icon { width: 16px; }
}
마이그레이션 팁
Tailwind v4로 업그레이드하면서 스타일이 사라지는 것을 발견했다면, &-- 또는 &__를 사용하는 BEM‑스타일 네스팅이 있는지 확인하고 명시적인 선택자로 교체하세요.