tailwindcss
tailwindcss copied to clipboard
Tailwind CSS v4 Selector Parsing Issue with Empty String Attribute
Tailwind CSS v4 Selector Parsing Issue with Empty String Attribute
Environment
- Tailwind CSS Version: 4.0.7
- Framework: Next.js 15.1.7
- Node.js Version: 22.14.0
- Browser: Chrome
- Operating System: Windows
Reproduction
Repository: https://github.com/coderrshyam/next.js-hook-webpack-error
Steps to Reproduce:
- Clone the repository:
git clone https://github.com/coderrshyam/next.js-hook-webpack-error.git
cd next.js-hook-webpack-error
- Install dependencies:
pnpm install
- Attempt to build the project:
pnpm build
Issue Description:
When attempting to build a Next.js project with Tailwind CSS v4, an issue occurs with CSS selector parsing, specifically for selectors containing attribute selectors with empty string values.
The problematic selector: .prose code[data-theme*=" "]
Behavior in Tailwind CSS v3 (Working Correctly)
In Tailwind CSS v3, the selector is parsed correctly:
Parser {
rule: '.prose code[data-theme*=" "]',
options: { lossy: false, safe: false },
position: 8,
css: '.prose code[data-theme*=" "]',
// ... other properties
}
Behavior in Tailwind CSS v4 (Incorrect)
In Tailwind CSS v4, the selector is not parsed correctly:
Parser {
rule: '.prose code[data-theme*=\\]',
options: { lossy: false, safe: false },
position: 8,
css: '.prose code[data-theme*=\\]',
// ... other properties
}
Expected Behavior
The parser in Tailwind CSS v4 should correctly handle the empty string in the attribute selector, similar to how it was handled in v3.
Actual Behavior
The parser in Tailwind CSS v4 seems to be escaping or misinterpreting the empty string in the attribute selector, leading to an incorrect parsing of the CSS rule.
Additional Notes
- This issue specifically occurs during the build process of a Next.js project.
- The problem appears to be isolated to cases where an attribute selector contains an empty string value.
Hey! This seems like an issue in the upstream handling of the CSS file, I can reproduce this without Tailwind CSS. The reason is that we minify the selector you mentioned to something like this (in it's most minimal form):
[data-attr=\ ] {
color: red;
}
This works in the browsers but will trip up Next.js/webpack right now.
I created an upstream bug report for this: https://github.com/vercel/next.js/issues/76269
ok
@philipp-spiess is there is plan to support ts config file for postcss
@coderrshyam I'd assume it should already work since we use jiti to load the config files. If you see any issues there please file a new bug report, thanks!
"Nice work, @philipp-spiess! Could you create a pull request in Next.js to support this TypeScript configuration file for PostCSS as well? I had previously created a PR (#79054), but it contains errors and couldn't be merged."
@coderrshyam I'm afraid that's not something we can help with, I don't know why Next.js limits the type of the PostCSS config file but my gut tells me it's there for a reason. Best to reach out to the Next.js maintainers for this!
Since there's an open issue for this for Next.js I'm gonna close this one here. There's not much we can do on our side.
There are, however, two workarounds!
- Update to the latest Next.js and build using
--turbopack. Turbopack uses different mechanisms to parse CSS and appears to handle this case fine; OR - Disable minification by passing in options to our PostCSS plugin:
/** @type {import('tailwindcss').Config} */
export default {
plugins: {
"@tailwindcss/postcss": {
// If you add this you can disable minification but still run Lightning CSS
optimize: { minify: false },
},
},
};