diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52cc9042cc3c..f8f8fb83ecf1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support opacity values in increments of `0.25` by default ([#14980](https://github.com/tailwindlabs/tailwindcss/pull/14980))
+### Fixed
+
+- Ensure that CSS inside Svelte `
`,
- 'src/components.css': css`
- .foo {
+ 'src/other.css': css`
+ .local {
@apply text-red-500;
+ animation: 2s ease-in-out 0s infinite localKeyframes;
+ }
+
+ :global(.global) {
+ @apply text-green-500;
+ animation: 2s ease-in-out 0s infinite globalKeyframes;
+ }
+
+ @keyframes -global-globalKeyframes {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 100%;
+ }
+ }
+
+ @keyframes localKeyframes {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 100%;
+ }
}
`,
},
@@ -74,7 +102,13 @@ test(
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
- await fs.expectFileToContain(files[0][0], [candidate`underline`, candidate`foo`])
+ await fs.expectFileToContain(files[0][0], [
+ candidate`underline`,
+ '.global{color:var(--color-green-500);animation:2s ease-in-out 0s infinite globalKeyframes}',
+ /\.local.svelte-.*\{color:var\(--color-red-500\);animation:2s ease-in-out 0s infinite svelte-.*-localKeyframes\}/,
+ /@keyframes globalKeyframes\{/,
+ /@keyframes svelte-.*-localKeyframes\{/,
+ ])
},
)
@@ -127,20 +161,48 @@ test(
`,
'src/App.svelte': html`
-
Hello {name}!
+ Hello {name}!
-
`,
- 'src/components.css': css`
- .foo {
+ 'src/index.css': css`
+ @import 'tailwindcss/theme' theme(reference);
+ @import 'tailwindcss/utilities';
+ `,
+ 'src/other.css': css`
+ .local {
@apply text-red-500;
+ animation: 2s ease-in-out 0s infinite localKeyframes;
+ }
+
+ :global(.global) {
+ @apply text-green-500;
+ animation: 2s ease-in-out 0s infinite globalKeyframes;
+ }
+
+ @keyframes -global-globalKeyframes {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 100%;
+ }
+ }
+
+ @keyframes localKeyframes {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 100%;
+ }
}
`,
},
@@ -148,30 +210,45 @@ test(
async ({ fs, spawn }) => {
await spawn(`pnpm vite build --watch`)
- let filename = ''
await retryAssertion(async () => {
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
- filename = files[0][0]
+ let [, css] = files[0]
+ expect(css).toContain(candidate`underline`)
+ expect(css).toContain(
+ '.global{color:var(--color-green-500);animation:2s ease-in-out 0s infinite globalKeyframes}',
+ )
+ expect(css).toMatch(
+ /\.local.svelte-.*\{color:var\(--color-red-500\);animation:2s ease-in-out 0s infinite svelte-.*-localKeyframes\}/,
+ )
+ expect(css).toMatch(/@keyframes globalKeyframes\{/)
+ expect(css).toMatch(/@keyframes svelte-.*-localKeyframes\{/)
})
- await fs.expectFileToContain(filename, [candidate`foo`, candidate`underline`])
+ await fs.write(
+ 'src/App.svelte',
+ (await fs.read('src/App.svelte')).replace('underline', 'font-bold bar'),
+ )
await fs.write(
- 'src/components.css',
- css`
- .bar {
- @apply text-green-500;
- }
- `,
+ 'src/other.css',
+ `${await fs.read('src/other.css')}\n.bar { @apply text-pink-500; }`,
)
+
await retryAssertion(async () => {
let files = await fs.glob('dist/**/*.css')
expect(files).toHaveLength(1)
let [, css] = files[0]
- expect(css).toContain(candidate`underline`)
- expect(css).toContain(candidate`bar`)
- expect(css).not.toContain(candidate`foo`)
+ expect(css).toContain(candidate`font-bold`)
+ expect(css).toContain(
+ '.global{color:var(--color-green-500);animation:2s ease-in-out 0s infinite globalKeyframes}',
+ )
+ expect(css).toMatch(
+ /\.local.svelte-.*\{color:var\(--color-red-500\);animation:2s ease-in-out 0s infinite svelte-.*-localKeyframes\}/,
+ )
+ expect(css).toMatch(/@keyframes globalKeyframes\{/)
+ expect(css).toMatch(/@keyframes svelte-.*-localKeyframes\{/)
+ expect(css).toMatch(/\.bar.svelte-.*\{color:var\(--color-pink-500\)\}/)
})
},
)
diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts
index 422437d60f4e..1eaf1d0f6fff 100644
--- a/packages/@tailwindcss-vite/src/index.ts
+++ b/packages/@tailwindcss-vite/src/index.ts
@@ -59,7 +59,7 @@ export default function tailwindcss(): Plugin[] {
if (!module) {
// The module for this root might not exist yet
if (root.builtBeforeTransform) {
- return
+ continue
}
// Note: Removing this during SSR is not safe and will produce
@@ -196,17 +196,17 @@ export default function tailwindcss(): Plugin[] {
let root = roots.get(id)
+ // If the root was built outside of the transform hook (e.g. in the
+ // Svelte preprocessor), we still want to mark all dependencies of the
+ // root as watched files.
if (root.builtBeforeTransform) {
root.builtBeforeTransform.forEach((file) => this.addWatchFile(file))
root.builtBeforeTransform = undefined
- // When a root was built before this transform hook, the candidate
- // list might be outdated already by the time the transform hook is
- // called.
- //
- // This requires us to build the CSS file again. However, we do not
- // expect dependencies to have changed, so we can avoid a full
- // rebuild.
- root.requiresRebuild = false
+ }
+
+ // We only process Svelte `