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

Global styles not supporting composed selectors like :is() #501

Closed
HerrCraziDev opened this issue Apr 8, 2022 · 10 comments · Fixed by #632 · May be fixed by #633
Closed

Global styles not supporting composed selectors like :is() #501

HerrCraziDev opened this issue Apr 8, 2022 · 10 comments · Fixed by #632 · May be fixed by #633

Comments

@HerrCraziDev
Copy link

Problem

Using the global attribute on a style block will prevent any use of composed CSS selectors inside it. Markup as simple as the following will trigger the error.

<style global>
    article :is(h1, h2) {
        font-family: "EB Garamond";
    }
</style>

Output

<redacted>/src/layouts/article.svelte:47:21 :global(...) must contain a single selector
 45 |      }
 46 |  
 47 |      :global(article) :global(:is(h1), :global(h2)) {
                            ^
 48 |          font-family: "EB Garamond";
 49 |      }

I would expect :global(article h1) :global(article h2) to be a more correct preprocessed output.

@MagDevX
Copy link

MagDevX commented Feb 25, 2023

svelte: 3.55.1
svelte-preprocess: 5.0.1

Having the same issue:

<style lang="scss" global>
.highlight {
    background: yellow;
}

div:has(input.highlight) {
    span {
        color: red;
    }
}

.test {
    input {
        @extend .highlight;
    }
}
</style>

Output

/src/routes/+page.svelte:320:0 :global(...) must contain a single selector

/src/routes/+page.svelte:320:0

318 |  }
 319 |  
 320 |  :global(div:has(input.highlight), :global(.test) :global(input)) :global(span) {
        ^
 321 |    color: red;
 322 |  }

A workaround would be to wrap the problematic part in :global(), but this is not feasible when the problematic part is in an external scss file that we are just extending inside the global style tag.

<style lang="scss" global>
@use 'node_modules/.../highlight.scss';

.test {
    input {
        @extend .highlight;
    }
}
</style>

@MagDevX
Copy link

MagDevX commented Feb 26, 2023

A potential fix would be to set the combinatorPattern to the following:

/(?<!\\)(?:\\\\)*([ >+~,]\s*)(?![^(]*\))(?![^[]+\]|\d)/g

It excludes the content of the parentheses.

@gbl08ma
Copy link

gbl08ma commented Jul 28, 2023

This bit me hard when migrating from Tailwind v2 to v3. The symptom was that dark mode in my app stopped being dark, it was stuck in light mode. They changed how class-based dark mode works, and it took me way too long to realize that the breakage was being caused by svelte-preprocess.

Selectors that should look like this:
:is(.dark .dark\:bg-black)

are instead emitted like this:
:is(.dark) :global(.dark\:bg-black)

when one brings in tailwind like this:

<style global lang="postcss">
	@tailwind base;
	@tailwind components;
	@tailwind utilities;
</style>

Quite the bummer. Now I'll have to find some workaround based on patching/forking svelte-preprocess or by doing string replacements on the resulting CSS bundle, and I'm not sure which approach I'm least looking forward to 😅

@alvissraghnall
Copy link

This bit me hard when migrating from Tailwind v2 to v3. The symptom was that dark mode in my app stopped being dark, it was stuck in light mode. They changed how class-based dark mode works, and it took me way too long to realize that the breakage was being caused by svelte-preprocess.

Selectors that should look like this: :is(.dark .dark\:bg-black)

are instead emitted like this: :is(.dark) :global(.dark\:bg-black)

when one brings in tailwind like this:

<style global lang="postcss">
	@tailwind base;
	@tailwind components;
	@tailwind utilities;
</style>

Quite the bummer. Now I'll have to find some workaround based on patching/forking svelte-preprocess or by doing string replacements on the resulting CSS bundle, and I'm not sure which approach I'm least looking forward to 😅

I'm having this exact issue right now. Any temp fixes so far?

@gbl08ma
Copy link

gbl08ma commented Jan 14, 2024

@alvissraghnall I'm sorry I'm some months late but it turns out I wasn't subscribed to this issue and only saw your message when checking if this issue was fixed. The "fix" I've found is to use patch-package to modify combinatorPattern. The patch looks like this:

diff --git a/node_modules/svelte-preprocess/dist/modules/globalifySelector.js b/node_modules/svelte-preprocess/dist/modules/globalifySelector.js
index fff3bd6..e1c72a9 100644
--- a/node_modules/svelte-preprocess/dist/modules/globalifySelector.js
+++ b/node_modules/svelte-preprocess/dist/modules/globalifySelector.js
@@ -9,7 +9,7 @@ exports.globalifySelector = void 0;
  * escaped combinators like `\~`.
  */
 // TODO: maybe replace this ugly pattern with an actual selector parser? (https://github.com/leaverou/parsel, 2kb)
-const combinatorPattern = /(?<!\\)(?:\\\\)*([ >+~,]\s*)(?![^[]+\]|\d)/g;
+const combinatorPattern = /(?<!\\)(?:\\\\)*([ >+~,]\s*)(?![^(]*\))(?![^[]+\]|\d)/g;
 function globalifySelector(selector) {
     const parts = selector.trim().split(combinatorPattern);
     const newSelector = [];

@Keavon
Copy link

Keavon commented Apr 18, 2024

Is this a fix someone would want to upstream so we don't have to use patch-package suggested by @gbl08ma?

@HerrCraziDev
Copy link
Author

+1, this has been left open for longer than it should !

@gregschmit
Copy link
Contributor

Has anyone found a condition where that modified regular expression fails? I am going to submit a PR so hopefully this can get fixed. Right now it's preventing me from using either tailwind (and daisy ui) with my svelte project.

@gregschmit
Copy link
Contributor

Ok, I opened a PR as I didn't see any existing PR for this change.

@HerrCraziDev
Copy link
Author

Thanks for the fix ! 👌

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