Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4] In Solid Start, & is outputted as & which breaks the styles #16133

Closed
DaniGuardiola opened this issue Jan 31, 2025 · 14 comments
Closed
Labels

Comments

@DaniGuardiola
Copy link

DaniGuardiola commented Jan 31, 2025

What version of Tailwind CSS are you using?

tailwindcss: v4.0.1

@tailwindcss/vite: 0.0.0-insiders.7f1d097

The insiders version is the latest as of this issue's publication, needed because #16052 hasn't been released stable yet. However, as mentioned below, the issue also happens with a PostCSS setup, so it doesn't seem tied to vite.

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

For example: Solid Start (repo version directly)

What version of Node.js are you using?

For example: v23.6.1

What browser are you using?

N/A

What operating system are you using?

N/A

Reproduction URL

solidjs/solid-start#1748

Describe your issue

Related Solid Start issue: solidjs/solid-start#1749

Tailwind CSS v4 (recently fixed to work with Solid Start) outputs & as & which breaks the styles.

For example, a class using a "dark theme" variant like this:

.dark\:bg-red-500 {
  &:where(.dark, .dark *) {
    background-color: var(--color-red-500);
  }
}

This is actually outputted like this:

.dark\:bg-red-500 {
  &:where(.dark, .dark *) {
    background-color: var(--color-red-500);
  }
}

It doesn't depend on the vite setup because it also happened with the alternative PostCSS-based setup. Unsure if the issue is on Solid Start's side or Tailwind CSS's side.

@DaniGuardiola DaniGuardiola changed the title [v4] [v4] In Solid Start, & is outputted as & which breaks the styles Jan 31, 2025
@philipp-spiess
Copy link
Member

Hey! I really don't know what's going on here but I noticed that when I upgrade to 4.0.3 (as well as test with local dev builds), this works again as expected 🤔

Image

For some reason the insider release does appear borked but I don't have an explanation as to why.

Given that the fix you wanted is already released, I was wondering if you can try to upgrade and let me know if there are still issues on your end?

@arthur-fontaine
Copy link

arthur-fontaine commented Feb 7, 2025

I got the same problem, but with Svelte. I guess this is the same bug. I created a repro: https://github.com/arthur-fontaine/repro-tailwind-vite-amp-bug. I will try to reduce the repro even more.

For now, I fixed this by registering the Tailwind config before the Svelte config.

export default defineConfig({
-  plugins: [svelte(), tailwindcss()],
+  plugins: [tailwindcss(), svelte()],
})

But I think this is an unattended behavior. The Tailwind Vite plugin should be able to compile correctly the CSS no matter the order of the plugins.

EDIT:

I just encountered a case where putting the Tailwind Vite plugin before the Svelte one make impossible to use @tanstack/svelte-query. So yes, The Tailwind Vite plugin should be able to compile correctly the CSS no matter the order of the plugins.

@DaniGuardiola
Copy link
Author

DaniGuardiola commented Feb 7, 2025

@philipp-spiess, it is still happening, at least in my actual repo (not the repro I shared). Let me try in the repro, too, just in case. For context, this is happening in WSL2, but I'm not sure it matters.


Edit: check the repro (in issue description) again. I've updated it to the latest version. Remember also that the issue also happened with the PostCSS setup. This makes Tailwind CSS v4 incompatible with Solid Start, and my upgrade is stuck :P

@DaniGuardiola
Copy link
Author

DaniGuardiola commented Feb 7, 2025

Cross-posting solidjs/solid-start#1749 (comment)


Reading through some of the links here (@arthur-fontaine's comment), it seems like a potential solution/workaround would be to have the tailwind vite plugin before the solid start (vinxi?) one. How can this be achieved in Solid Start?

Update: I just tried forcing the ordering to "pre" (docs), but it doesn't seem to make sense because tailwind() actually returns a series of plugins that already have this setting. Not sure what else to try.

@DaniGuardiola
Copy link
Author

Ah, important observation, regarding my actual project (not repro):

  • When JavaScript is enabled, the inspector shows two selectors: one that doesn't work and one that does (and shows up with &. Hence, the styles do work.

Image

  • When following to the source, both selectors point to the same place, where the & can be seen.

Image

  • With JavaScript disabled, only the "empty" version of the selector shows up in the inspector.

Image

So, it seems like it might be a problem with JavaScript when disabled, which might hint that the problem is specific to the server-side build. The most confusing part of all this is, when I try in the repro, it doesn't work with or without JavaScript enabled :/

I might share my project (WIP branch) in case it's useful for debugging. I don't really know what's causing the difference.

@birtles
Copy link

birtles commented Feb 15, 2025

I'm currently trying to debug something similar in an Astro project using the vite plugin where before:content-['#'] is transformed into:

  .before\:content-\[\&\#x27\;\#\&\#x27\;\] {
    &::before {
      content: var(--tw-content);
      --tw-content: '#';
      content: var(--tw-content);
    }
  }
  .before\:content-\[\'\#\'\] {
    &::before {
      content: var(--tw-content);
      --tw-content: '#';
      content: var(--tw-content);
    }
  }

I'm not sure yet what's producing the escaped version but it's tripping up postcss/lightning CSS because the --tw-content: '#'; part is invalid.

@birtles
Copy link

birtles commented Feb 15, 2025

I might be looking at a different problem, however, because I notice if I remove all url()s from my styles the problem goes away which suggests it might be the URL rewriter to blame:

if (!css.includes('url(') && !css.includes('image-set(')) {
return css
}

@DaniGuardiola
Copy link
Author

I will insist once more that I observed this behavior with PostCSS too, and not exclusively with Vite :)

However, I think a fix on Solid's side has been submitted (see ryansolid/dom-expressions#401) so, if that was the root of the issue, it should be fixed once merged.

@philipp-spiess
Copy link
Member

@DaniGuardiola Ah, I must have missed this! Glad that's fixed upstream though. I have a PR open that completely reworks the Vite extension and wanted to make sure it also resolves this issue but yeah it seems like this Solid issue is unrelated to Vite!

@birtles Do you have a repro for your Astro issue?

@birtles
Copy link

birtles commented Feb 22, 2025

@birtles Do you have a repro for your Astro issue?

Not yet. I'm trying to work out what is triggering it so I can create a suitable repro but it's slow going debugging minimized code.

So far I can see that the errant node is already there when the AST is finished being built here:

let newAst = api.build(newCandidates)

Image

So it doesn't appear to be a serialization issue.

Also, we don't seem to be escaping it twice here:

let selector = `.${escape(candidate.raw)}`

So I'm not sure where it's creeping in yet.

@birtles
Copy link

birtles commented Feb 22, 2025

Oh, looks like the bogus string is coming from getSharedCandidates so I guess it might be fixed by 88b762b.

@birtles
Copy link

birtles commented Feb 22, 2025

Yep, appears to be fixed in 4.0.8!

@philipp-spiess
Copy link
Member

Awesome! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants