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(...) .child selector is given svelte- suffix if there is a variable class name in the html #4314

Closed
gushogg-blake opened this issue Jan 24, 2020 · 4 comments · Fixed by #4332
Labels

Comments

@gushogg-blake
Copy link

If there is an element with a class={someVariable} attribute in the markup, :global(body) .className child selectors get suffixed, and therefore don't apply to child components.

For example, if you have a parent component that applies a "theme" class to its top-level element, and has child selectors to style matching elements within all its child components depending on the theme, it doesn't work if the theme class is a variable (but does if it's hard-coded as e.g. <div class="purple">.

(The variable class is what's relevant - any element with a non-hard-coded class name in the parent component will break it.)

REPL:

@Conduitry Conduitry added bug and removed bug labels Jan 24, 2020
@Conduitry
Copy link
Member

I do think there's a bug here, but I don't think it's what you're saying it is.

.purple :global(.text) is the selector that you should be using to refer to .text elements in any descendant of this component's .purple elements. This selector works with or without the span you mention.

:global(.purple) .text is supposed to match elements in this component with .text that have .purple among their ancestors. As far as Svelte can tell at compile time, this might match <span class={cls}></span> but it won't match <div class="purple"><Child/></div>.

What does seem to be a bug to me is that, starting from your example, if you remove the span, Svelte doesn't see that as an unused style to be removed. :global(.purple) .text shouldn't match anything because there isn't anything in this component that could match .text.

@vipero07
Copy link

vipero07 commented Jan 24, 2020

:global(.purple) .text is supposed to match elements in this component with .text that have .purple among their ancestors. As far as Svelte can tell at compile time, this might match <span class={cls}></span> but it won't match <div class="purple"><Child/></div>.

I think <div class="purple"><Child/></div> should match per your description, as the child element has a .text class in it.

Consider the flattened form: <div class="purple"><span class="text">should be purple?</span></div>

Child being a svelte component shouldn't change that. I think the right way to go about this though would be :global(.purple .text) which works.

If I understand correctly though, anything not :global() should be interpreted as a local class, so I do get where you are coming from regarding the issue.

@gushogg-blake
Copy link
Author

Thanks for clarifying @Conduitry. I was under the impression that :global made the whole selector global, but the behaviour you specify makes more sense.

@Conduitry
Copy link
Member

Fixed in 3.18.1 - https://svelte.dev/repl/0cf466aa625c42ed9dc845d0b46d1905?version=3.18.1 - in that the text is now not purple regardless of the presence of <span class={cls}></span>. As mentioned above, you need to use :global() around any portion of the selector that doesn't refer to this component, whether it's above us or below us in the tree.

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

Successfully merging a pull request may close this issue.

3 participants