Skip to content

feat: allow :global in more places (alternative) #12560

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

Merged
merged 25 commits into from
Jul 25, 2024
Merged

Conversation

dummdidumm
Copy link
Member

Alternative to #12509 - this PR switches back to removing the preceeding descendant combinator before the :global, and also makes sure that the nested case (div { :global.x { ... } }) is treated equivalently by prepending a & to the output (div { &.x { ... } }).

Fixes #10513

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

Copy link

changeset-bot bot commented Jul 23, 2024

🦋 Changeset detected

Latest commit: ff6a57c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

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

@Rich-Harris
Copy link
Member

The messages still reference 'a :global {...} block', and they should probably be updated to something like 'a :global selector'. Though it'd become a little confusing that it only meant :global and not :global(...)... gah

Comment on lines 95 to 97
The difference between `:global` and `:global(...)` is that `:global(...)` only makes all styles within its braces global, whereas `:global` makes all styles coming after it global, including those in nested CSS.

If `:global` is preceeded by a descendant combinator, the combinator is removed from the output. That means that `div :global.x` is equivalent to `div.svelte-hash.x`.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
The difference between `:global` and `:global(...)` is that `:global(...)` only makes all styles within its braces global, whereas `:global` makes all styles coming after it global, including those in nested CSS.
If `:global` is preceeded by a descendant combinator, the combinator is removed from the output. That means that `div :global.x` is equivalent to `div.svelte-hash.x`.
> Some preprocessors will flatten nested selectors, turning the second example above into a `div :global strong` selector. As such this form is also supported, though not recommended.

Copy link
Member Author

@dummdidumm dummdidumm Jul 24, 2024

Choose a reason for hiding this comment

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

Why remove the existing sections? We could adjust them to only have global-with-nesting examples.
I would also not use preprocessors as an argument and instead that they are semantically equivalent.

Copy link
Member

Choose a reason for hiding this comment

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

Because we shouldn't be recommending div :global strong, at least not as long as div :global(strong) is supported. That's just two very similar ways of achieving the same thing, which is something we generally strive to avoid.

Even if there are multiple selectors, I would argue that this...

a :global(b c d) {...}

...is much clearer than this:

a :global b c d {...}

I really think that from an authoring perspective, we should promote :global {...} as the default, and :global(...) as a more occasional escape hatch, and :global selector not at all other than in the context of 'this happens to work because reasons'.

Copy link
Member Author

Choose a reason for hiding this comment

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

I would be ok with removing the second paragraph though I think it's worthwhile to know how to reason about it, so if there's a way to phrase it while using an example that doesn't promote the "bad" way, shouldn't we keep it?
And the first example doesn't mention anything with regards to how to write it, it provides an important comparison IMO and so I'd like to keep it

Copy link
Member

Choose a reason for hiding this comment

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

ok what about this? we replace all the element selectors with class selectors, to make them more abstract and so that we can have multiple selectors after the :global:

.a :global {
	/* applies to every `.b .c .d` element, in any component,
	   that are inside an `.a` element in this component
	.b .c .d {...}
}

Then we can do this:

Suggested change
The difference between `:global` and `:global(...)` is that `:global(...)` only makes all styles within its braces global, whereas `:global` makes all styles coming after it global, including those in nested CSS.
If `:global` is preceeded by a descendant combinator, the combinator is removed from the output. That means that `div :global.x` is equivalent to `div.svelte-hash.x`.
> Some preprocessors will flatten nested selectors, turning the second example above into an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped. As such this form is also supported, but the nested form is recommended instead when writing styles.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moving the info into the code example works for me 👍 I'd still like to avoid using preprocessors as the reasoning and instead say "because they are semantically equivalent, this is also allowed.."

Copy link
Member Author

Choose a reason for hiding this comment

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

pushed a tweak, let me know what you think

@dummdidumm
Copy link
Member Author

tweaked the error messages - I don't think the similarity between :global and :global(...) is that bad - it's pretty clear from context which one you're using


> A :global {...} block can only appear at the end of a selector sequence (did you mean to use :global(...) instead?)
> A :global {...} block at the very beginning cannot be modified by other selectors
Copy link
Member

Choose a reason for hiding this comment

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

We're going to need to rewrite all the ':global {...} block' messages to account for :global .whatever

Suggested change
> A :global {...} block at the very beginning cannot be modified by other selectors
> A `:global` selector can only be modified if it is a descendant of other selectors

Copy link
Member Author

@dummdidumm dummdidumm Jul 24, 2024

Choose a reason for hiding this comment

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

Either Github played a trick on you and showed an outdated version or you commented right before I pushed changes in that direction - either way, I adjusted the messages.

@Rich-Harris Rich-Harris merged commit 13d86e9 into main Jul 25, 2024
9 checks passed
@Rich-Harris Rich-Harris deleted the css-global-tweaks-v2 branch July 25, 2024 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tailwind @apply breaks with Svelte 5 (alpha 57)
2 participants