为什么 BEM 嵌套在 Tailwind v4 中会失效
发布: (2026年3月18日 GMT+8 20:48)
3 分钟阅读
原文: Dev.to
Source: Dev.to
所以今天我花了一些时间调试为什么某些 CSS 样式没有生效。结果发现 Tailwind v4 静悄悄地把在 Tailwind v3 中可用的功能弄坏了。
原始的 BEM‑style 嵌套
/* 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‑style 嵌套 的区别。
原生 CSS 与 Sass 嵌套的区别
| 功能 | 原生 CSS 支持 | Sass 支持 | Tailwind v3 | Tailwind v4 |
|---|---|---|---|---|
&:hover(伪类) | ✅ | ✅ | works | works |
& .child(组合选择器) | ✅ | ✅ | works | works |
&.another-class(链式) | ✅ | ✅ | works | works |
&--modifier(字符串拼接) | ❌ | ✅ | works | broken |
&__element(字符串拼接) | ❌ | ✅ | works | broken |
- 原生 CSS 嵌套(浏览器真正理解的)只允许
&用于伪类、组合选择器和简单的链式选择。 - Sass 则额外提供了字符串拼接的能力,使得
&--open、&__icon这类 BEM‑style 选择器成为可能。这并不是真正的 CSS。
Tailwind v4 做了什么改变?
- Tailwind v3 使用
postcss-nested,它模拟了 Sass 的拼接行为。 - Tailwind v4 改用了 Lightning CSS,它遵循官方的 CSS 嵌套规范,因此 不支持字符串拼接。BEM 嵌套会直接静默失败。
解决办法
改为写完整的类名,而不是依赖拼接:
/* 之前(在 v4 中失效) */
.dropdown {
&--open { background: blue; }
&__icon { width: 16px; }
}
/* 之后(在所有环境都可用) */
.dropdown--open { background: blue; }
.dropdown__icon { width: 16px; }
仍然可以嵌套原生 CSS 支持的部分:
.dropdown {
&:hover { background: gray; }
& .dropdown__icon { width: 16px; }
}
迁移提示
如果你升级到 Tailwind v4 后发现样式消失,检查是否有使用 &-- 或 &__ 的 BEM‑style 嵌套。将它们替换为显式的选择器即可。