为什么 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 v3Tailwind v4
&:hover(伪类)worksworks
& .child(组合选择器)worksworks
&.another-class(链式)worksworks
&--modifier(字符串拼接)worksbroken
&__element(字符串拼接)worksbroken
  • 原生 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 嵌套。将它们替换为显式的选择器即可。

相关链接: Tailwind CSS GitHub Issue #18522

0 浏览
Back to Blog

相关文章

阅读更多 »

公平在行动

🎨 从偏见到平衡 — 前端性别公平的故事 💡 概念 - 打破系统性偏见 - 公平优于平等 - 共同崛起 🚀 Code javascript imp...