Issue with latest tailwind (4.0.8) - styles disappear / not generated by tailwind
The issue
I am using tw4 in my vite project, with vite plugin. In the project itself it works as expected. In ladle it used to work before, but all of a sudden it stopped (still works in main app tho) after I updated my deps - tailwind just does not generate the styles needed by components, but generates ones used by ladle (added via .ladle/components.tsx.
There is nothing specific about ladle's config, it uses the same configs and roughly same styles as the main app.
Not sure if it is a ladle issue - or rather a tailwind issue, but as main app works and ladle doesn't - I suppose there is something specific either with ladle or how I am using it.
Workaround
Reverting tailwindcss and @tailwindcss/vite from 4.0.8 back to 4.0.6 and locking versions helps.
Reproduction
Was unable to start it in stackblitz (as tailwind apparently needs a native extensions, and they are forbidden in stackblitz)
Therefore I created a repo: https://github.com/andrienko/ladle-issue-reproduction
(it is a stripped down version of my setup, with all important stuff remaining, in case something is wrong with my setup)
Environment
Reproduces on windows 11 / macos ventura / arch 2025.02.01, and in latest chrome/firefox. Doubt the environment is relevant
@tajo Same issue here. Can we please fix this asap? It's an important issue.
Same
Seeing this as well. Reverting to 4.0.6 did not resolve this for me.
Have the same problem. Can anyone help?
I found a temporary solution. You need to create a css file inside .ladle and import tailwind
example @import 'tailwindcss' source(path to components);
don't forget to import index.css into ./ladle/components.tsx
UPD:
enough to specify in source (path of folders where your components are located) when importing tailwind
@source "../../shared/ui/"; // path to ui components
I added this to tailwind.css config file
That solved the problem Detecting classes in source files
Hi guys, thanks to your suggestion I found a solution that worked for me. I'm using:
tailwindcss: 4.1.6@ladle/react: 5.0.3daisyui: 5.0.35
I created a .ladle folder in the root project with 2 files:
components.tsxthat just import the second file (import "./theme.css")theme.css
@import "../src/index.css";
@source "../src/components/";
In my index.css there is another import to the real theme.css file where I configured daisyui with tailwind.
Hope it can helps someone
Its something to deal with source parsing. Here is the best solution I found without locking versions. Basically, you want to specify sources for Ladle only
Split your src/index.css into two parts
src/index.css
@import "tailwindcss";
@import "@/theme.css";
src/theme.css (in my case I use shadcn)
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
Then, you need to set up .ladle in the next way:
.ladle/components.tsx
import "./ladle.css";
import "@/index.css";
.ladle/ladle.css
@import "tailwindcss" source("../src/");
@import "@/theme.css";
Thanks @pelykh. That did it.
I tried a bunch of combinations and finally this is what worked thanks to your comment:
/* .ladle/styles.css */
@import "tailwindcss" source("../src/");
@import "../src/styles.css";
and then
// .ladle/components.tsx
import "./styles.css";