Why BEM Nesting Breaks in Tailwind v4
Source: Dev.to
So today I spent some time debugging why certain CSS styles weren’t applying. Turns out Tailwind v4 quietly broke something that worked in Tailwind v3.
Original BEM‑style nesting
/* BEM nesting */
.dropdown {
background: white;
&--open {
background: blue;
}
&__icon {
width: 16px;
}
}
In Tailwind v3 this compiled to:
.dropdown { background: white; }
.dropdown--open { background: blue; }
.dropdown__icon { width: 16px; }
In Tailwind v4 nothing is output—no error, no warning, just silence.
What still works
.dropdown {
&:hover { background: gray; }
& .child { color: red; }
}
&:hover works, but &--open does not. The reason lies in the difference between native CSS nesting and Sass‑style nesting.
Native CSS vs. Sass nesting
| Feature | Native CSS support | Sass support | Tailwind v3 | Tailwind v4 |
|---|---|---|---|---|
&:hover (pseudo‑class) | ✅ | ✅ | works | works |
& .child (combinator) | ✅ | ✅ | works | works |
&.another-class (chaining) | ✅ | ✅ | works | works |
&--modifier (string concat) | ❌ | ✅ | works | broken |
&__element (string concat) | ❌ | ✅ | works | broken |
- Native CSS nesting (what browsers understand) only allows
&for pseudo‑classes, combinators, and simple chaining. - Sass adds the ability to concatenate strings with
&, enabling BEM‑style selectors like&--openor&__icon. This is not real CSS.
What changed in Tailwind v4?
- Tailwind v3 used
postcss-nested, which emulated Sass’s concatenation behavior. - Tailwind v4 switched to Lightning CSS, which follows the official CSS nesting spec and therefore does not support string concatenation. BEM nesting simply fails silently.
Fixing the issue
Write the full class name instead of relying on concatenation:
/* Before (broken in v4) */
.dropdown {
&--open { background: blue; }
&__icon { width: 16px; }
}
/* After (works everywhere) */
.dropdown--open { background: blue; }
.dropdown__icon { width: 16px; }
You can still nest the parts that native CSS supports:
.dropdown {
&:hover { background: gray; }
& .dropdown__icon { width: 16px; }
}
Migration tip
If you’re upgrading to Tailwind v4 and notice styles disappearing, check for any BEM‑style nesting that uses &-- or &__. Replace those with explicit selectors.
Related: Tailwind CSS GitHub Issue #18522