Repository: tailwindlabs/tailwindcss

Problem statement:
Cannot use HTML style tag with Vite to apply a theme
<!-- Please provide all of the information requested below. We're a small team and without all of this information it's not possible for us to help and your bug report will be closed. -->

**What version of Tailwind CSS are you using?**

v4.0.1

**What build tool (or framework if it abstracts the build tool) are you using?**

Latest Vite with autoprefixer

**What version of Node.js are you using?**

NodeJS v22.10.0

**What browser are you using?**

Brave

**What operating system are you using?**

macOS

**Reproduction URL**

```html
<!DOCTYPE html>
<html>
	<head>
		<style>
			@import "tailwindcss";
			@layer components {
				h1{
					@apply text-2xl;
				}
			}
		</style>
	</head>
	<body>
    <h1>Test</h1>
  </body>
</html>
```

Vite config
```js
module.exports = {
	root: "./example",
	base: "./",
	appType: "custom",
	build: {
		rollupOptions: {
			input: "./example/test.html",
		},
		outDir: "./example-min/",
		emptyOutDir: true,
		copyPublicDir: false,
	},
	plugins: [
		tailwindcss(),
	],
	css: {
		postcss: {
			plugins: [autoprefixer()],
		},
	},
}
```

**Describe your issue**

We have single HTML files which are report templates in a facility for analysis reportings that are styled with tailwindcss. These are later processed by Vite to reduce their size and to process tailwindcss classes. We aren't able to support external CSS or JS here since these templates are generated by another tool which has its own syntax and templates. When processing these HTML with Vite tailwindcss seems to ignore inline CSS even with `text/tailwindcss`. Using the CDN works fine, but our reports need to work offline (companies that size do not allow these machines to have internet access on pruporse ofc). The reason we use the style tag is because that way we can provided a versioned theme to each report template and do not need to touch our template files which consist of many smaller modules that we do not want to touch that often and because each customer can have its own styled theme or custom styles for individuallity.


Hints:
At best it would be if `<style type="text/tailwindcss">` is allowed in Vite, taken by tailwind and later replaced with `<style>` so other post processors can like minify the contents if not already.

Patch:
diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts
--- a/packages/@tailwindcss-vite/src/index.ts
+++ b/packages/@tailwindcss-vite/src/index.ts
@@ -8,6 +8,7 @@ import type { Plugin, ResolvedConfig, Rollup, Update, ViteDevServer } from 'vite
 
 const DEBUG = env.DEBUG
 const SPECIAL_QUERY_RE = /[?&](raw|url)\b/
+const INLINE_STYLE_ID_RE = /[?&]index\=\d+\.css$/
 
 const IGNORED_DEPENDENCIES = ['tailwind-merge']
 
@@ -312,7 +313,7 @@ function isPotentialCssRootFile(id: string) {
   if (id.includes('/.vite/')) return
   let extension = getExtension(id)
   let isCssFile =
-    (extension === 'css' || id.includes('&lang.css')) &&
+    (extension === 'css' || id.includes('&lang.css') || id.match(INLINE_STYLE_ID_RE)) &&
     // Don't intercept special static asset resources
     !SPECIAL_QUERY_RE.test(id)
 


Test patch:
diff --git a/integrations/vite/html-style-blocks.test.ts b/integrations/vite/html-style-blocks.test.ts
new file mode 100644
--- /dev/null
+++ b/integrations/vite/html-style-blocks.test.ts
@@ -0,0 +1,58 @@
+import { html, json, test, ts } from '../utils'
+
+test(
+  'transforms html style blocks',
+  {
+    fs: {
+      'package.json': json`
+        {
+          "type": "module",
+          "dependencies": {
+            "tailwindcss": "workspace:^"
+          },
+          "devDependencies": {
+            "@tailwindcss/vite": "workspace:^",
+            "vite": "^6"
+          }
+        }
+      `,
+      'vite.config.ts': ts`
+        import { defineConfig } from 'vite'
+        import tailwindcss from '@tailwindcss/vite'
+
+        export default defineConfig({
+          plugins: [tailwindcss()],
+        })
+      `,
+      'index.html': html`
+        <!doctype html>
+        <html>
+          <body>
+            <div class="foo"></div>
+            <style>
+              .foo {
+                @apply underline;
+              }
+            </style>
+          </body>
+        </html>
+      `,
+    },
+  },
+  async ({ fs, exec, expect }) => {
+    await exec('pnpm vite build')
+
+    expect(await fs.dumpFiles('dist/*.html')).toMatchInlineSnapshot(`
+      "
+      --- dist/index.html ---
+      <!doctype html>
+      <html>
+        <body>
+          <div class="foo"></div>
+          <style>.foo{text-decoration-line:underline}</style>
+        </body>
+      </html>
+      "
+    `)
+  },
+)