Tailwind CSS v4 and Svelte 5 #14668
Replies: 2 comments 7 replies
-
I would prefer the post approach, splitting it in two and requireing a svelte preprocessor makes the pipeline more complex and slower too. As far as i understand this would limit tailwind v4 support to svelte5, as the svelte4 compiler is more strict regarding css syntax and can't handle v5 passes through If you have a working testsuite with svelte, vite and tailwind v4, it would be great to hook that up to https://github.com/sveltejs/svelte-ecosystem-ci and https://github.com/vitejs/vite-ecosystem-ci once you enter rc phase so we can continue to monitor compatibility. |
Beta Was this translation helpful? Give feedback.
-
I may be the odd man out here, but my preference would be to do something like the following:
That would also solve sveltejs/language-tools#2321 Assuming the approach works, it likely wouldn't require much code change on your part. I'm just about to leave for vacation, but you could try prototyping it. I do think in either case though that you really should generate source maps. |
Beta Was this translation helpful? Give feedback.
-
We're working on getting Tailwind CSS v4 ready for a release and need some guidance on how to best integrate Svelte
<style>
tag support into our Vite extension.Tailwind CSS users use features like the
@apply
directive that allows you to create custom CSS classes and fill them up with Tailwind CSS utilities directly from within their scoped Svelte components:In order to make this work in Tailwind CSS v4, we need the ability to transform the stylesheets inside the Svelte
<style>
tag.There are two ways we can intercept these stylesheets:
transform
hook to intercept the styles afterwards.Pre-processing
This was the approach necessary with our earlier alpha experiments as Svelte 4 was very strict about what CSS is allowed inside
<style>
tags and would make it impossible to make our syntax pass through (we, for example, rely heavily on CSS nesting).Being able to process the styles before Svelte sees it also works great with features like our newly introduced
@import "…" reference
option which will remove all non-Tailwind-CSS-config settings from the imported stylesheets so the Svelte compiler won't see (and warn) about any unexpected global styles when importing your Tailwind CSS theme.In order to register the pre-processor, we can either have the Vite plugin automatically inject it or expose the pre-processor as a separate plugin (
@tailwindcss/svelte
). The latter option is a bit more initial setup work but allows static analysis tools to also detect the extension.Post-processing
This is our preferred approach and the approach that works for our existing Vue and Astro integration as well. In this case, we rely on Vite's
transform
hooks.The good news is that it seems like Svelte 5 doesn't suffer from the same strictness as Svelte 4 anymore. There are still some limitations though, the most pressing one is that it's not possible to import your configuration using the
@import "…" reference
API without getting warnings.This is because the
@import
is seemingly resolved before the Svelte compiler sees it which will create a CSS like this that might now contain style rules that Tailwind CSS will later throw out. Svelte doesn't know about the post-process step and will only warn about unused selectors:becomes
In order for us to use this approach, we'd need a way to silence these warnings. One option to consider is maybe enforce a
<style lang="tailwindcss">
attribute on all styles that Tailwind CSS should process so that Svelte knows about the post-processing step.FAQ
What about static analysis tools?
One issue that both approaches have right now is that when running against the static analysis tool (
npx sv check
), the analyzer doesn't know about Tailwind CSS. This results in warnings like the following when e.g. using a@theme
directive for config:How does this work with scoping?
For the features we want to support inside
<style>
blocks, we will operate on the classes passed to the Tailwind CSS compiler. In case of using a post-processor, this means the input class names will already be scoped correctly. Some utilities might be creating new rules. These, however, will be nested under the existing class name using CSS nesting.Resource reloading?
We require
@import
to work according to the spec. If no other pre-processor is running, Tailwind CSS will resolve imports and return the dependencies correctly in both scenarios.What about utility class generation?
It is recommended to set up a global
.css
file that will be used to initialize the CSS variables from your Tailwind CSS theme and that contains all utility classes. For this, we use a regulartransform
in our Vite plugin to scan utilities being used (by reading all modules) and to transform.css
files. This already works and is unrelated to Svelte.@tailwind utilities
, the placeholder to generated utility classes, is not supported within Svelte<style>
tags.Open Question
We'd like your input to align on an approach to choose for processing Tailwind CSS styles inside
<style>
tags going forward, more specifically:Beta Was this translation helpful? Give feedback.
All reactions