Skip to content

Conversation

Conduitry
Copy link
Member

I finally sat down and wrote this. It may not stem the tide of feature requests, but it would be helpful to have a single thing to point at. I'd love some feedback on the wording here.

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

@changeset-bot
Copy link

changeset-bot bot commented Sep 10, 2023

⚠️ No Changeset found

Latest commit: 8bf623b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment on lines 136 to 142
No.

Svelte's component style scoping works by generating a class unique to the given component, and then adding it to the relevant elements in the component that are under Svelte's control, and then also adding it to each of the selectors in that component's styles. If the compiler can't see which elements a given selector applies to, it has two options if it were to keep it, both of them bad.

If it still adds the scoping class to the selector, there is no guarantee that it will match the expected elements in the component, especially if they were created by a child component or something like `{@html}`. If it keeps the selector without adding the scoping class to it, it will become a global style, affecting your entire page. The third option, which is what Svelte takes, is to remove the styles from the component and warn you about them.

If you need to style something that Svelte can't identify at compile time, you will need to explicitly opt in to global styles by using `:global(...)`. But also keep in mind that you can wrap `:global(...)` around only part of a selector. `.foo :global(.bar) { ... }` will style any `.bar` elements that appear within the component's `.foo` elements. As long as there's some parent element in the current component to start from, partially global selectors like this will almost always be able to get you what you want.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for writing this up! what do you think about this minor re-arrangement

Suggested change
No.
Svelte's component style scoping works by generating a class unique to the given component, and then adding it to the relevant elements in the component that are under Svelte's control, and then also adding it to each of the selectors in that component's styles. If the compiler can't see which elements a given selector applies to, it has two options if it were to keep it, both of them bad.
If it still adds the scoping class to the selector, there is no guarantee that it will match the expected elements in the component, especially if they were created by a child component or something like `{@html}`. If it keeps the selector without adding the scoping class to it, it will become a global style, affecting your entire page. The third option, which is what Svelte takes, is to remove the styles from the component and warn you about them.
If you need to style something that Svelte can't identify at compile time, you will need to explicitly opt in to global styles by using `:global(...)`. But also keep in mind that you can wrap `:global(...)` around only part of a selector. `.foo :global(.bar) { ... }` will style any `.bar` elements that appear within the component's `.foo` elements. As long as there's some parent element in the current component to start from, partially global selectors like this will almost always be able to get you what you want.
No. Svelte removes the styles from the component and warns you about them in order to prevent issues that would otherwise arise.
Svelte's component style scoping works by generating a class unique to the given component, adding it to the relevant elements in the component that are under Svelte's control, and then adding it to each of the selectors in that component's styles. There would be two bad options for keeping a style selector in a case where the compiler can't see which elements it applies to:
- If it still adds the scoping class to the selector, there is no guarantee that the given style will match the expected elements in the component, especially if they were created by a child component or something like `{@html}`.
- If it keeps the selector without adding the scoping class to it, the given style will become a global style, affecting your entire page.
If you need to style something that Svelte can't identify at compile time, you will need to explicitly opt into global styles by using `:global(...)`. But also keep in mind that you can wrap `:global(...)` around only part of a selector. `.foo :global(.bar) { ... }` will style any `.bar` elements that appear within the component's `.foo` elements. As long as there's some parent element in the current component to start from, partially global selectors like this will almost always be able to get you what you want.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've tweaked your suggestions a bit and have pushed e16e0a3.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


Svelte's component style scoping works by generating a class unique to the given component, adding it to the relevant elements in the component that are under Svelte's control, and then adding it to each of the selectors in that component's styles. When the compiler can't see what elements a style selector applies to, there would be two bad options for keeping it:

- If it keeps the selector and adds the scoping scoping class to it, there is no guarantee that the selector will match the expected elements in the component, and they definitely won't if they were created by a child component or `{@html ...}`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason github won't let me make a suggestion here, but: 'there is no guarantee that the selector will match the expected elements' is incorrect, I think? it's guaranteed not to match anything;

If it keeps the selector and adds the scoping class to it, it won't match any elements inside the component

Also, I'm not sure if 'scoping scoping' was a reference to the fact that we sometimes add the scoping class twice

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could theoretically match, I think, if the user programmatically added a matching class to an element that was already getting the scoping class applied for another reason. (This is also adjacent to what Dominik and I were discussing in Discord about vite-plugin-svelte's behavior.) Since this is the FAQ entry we'll point people to when they request this feature which seems quite reasonable on the surface, I wanted to be very careful about what I say is impossible versus just unlikely. I'm happy to change this to something else if you think that would be a good idea.

lol, 'scoping scoping' is in fact a copyediting failure. Will fix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tweaked "no guarantee" to "likely not". Will go ahead and merge now. Feel free to tweak or revert if you disagree with my change

@benmccann benmccann merged commit 16504d1 into sveltejs:master Sep 15, 2023
@Conduitry Conduitry deleted the no branch September 16, 2023 04:11
kelvinsjk pushed a commit to kelvinsjk/svelte that referenced this pull request Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants