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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
45137f0
`div { :global { &.x { ... } } }` is equivalent to `div:global.x { ..…
dummdidumm Jul 19, 2024
beadb2b
finalize
dummdidumm Jul 19, 2024
c24b602
replace obsolete breaking change (which turned out to be a wrong chan…
dummdidumm Jul 19, 2024
13fa451
changeset
dummdidumm Jul 19, 2024
b24253e
regenerate types
dummdidumm Jul 19, 2024
1069207
Update sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-…
dummdidumm Jul 22, 2024
d39e8ca
always remove descendant selector before global
dummdidumm Jul 22, 2024
80a38d7
Merge branch 'css-global-tweaks' of https://github.com/sveltejs/svelt…
dummdidumm Jul 22, 2024
0c12e48
error on lone `:global` with nested `&`, revert "remove spaces" rule
dummdidumm Jul 22, 2024
492a9b6
regenerate types
dummdidumm Jul 22, 2024
f5f5846
documentation
dummdidumm Jul 22, 2024
d11556c
oops
dummdidumm Jul 22, 2024
1f8bf93
switch to removing descendant combinator
dummdidumm Jul 23, 2024
10988dc
fix
dummdidumm Jul 23, 2024
86eeeab
revert combinator validation relaxation
dummdidumm Jul 24, 2024
7c640ee
error on first global being modified
dummdidumm Jul 24, 2024
8ba8511
tweak docs
dummdidumm Jul 24, 2024
38e6147
tweak error messages
dummdidumm Jul 24, 2024
1f0fe45
Update documentation/docs/02-template-syntax/05-styles-and-classes.md
dummdidumm Jul 24, 2024
669e8c0
clarify
Rich-Harris Jul 25, 2024
0984835
tweak messages
Rich-Harris Jul 25, 2024
03737b3
update tests
Rich-Harris Jul 25, 2024
db1679c
tweak docs
Rich-Harris Jul 25, 2024
57af89e
tweak `:global(...)` docs
Rich-Harris Jul 25, 2024
ff6a57c
tweak docs
Rich-Harris Jul 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tricky-balloons-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

feat: allow `:global` in more places
47 changes: 34 additions & 13 deletions documentation/docs/02-template-syntax/05-styles-and-classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,28 @@ This works by adding a class to affected elements, which is based on a hash of t
</style>
```

## :global
## :global(...)

To apply styles to a selector globally, use the `:global(...)` modifier.
To apply styles to a single selector globally, use the `:global(...)` modifier:

```svelte
<style>
:global(body) {
/* this will apply to <body> */
/* applies to <body> */
margin: 0;
}

div :global(strong) {
/* this will apply to all <strong> elements, in any
component, that are inside <div> elements belonging
to this component */
/* applies to all <strong> elements, in any component,
that are inside <div> elements belonging
to this component */
color: goldenrod;
}

p:global(.red) {
/* this will apply to all <p> elements belonging to this
component with a class of red, even if class="red" does
not initially appear in the markup, and is instead
added at runtime. This is useful when the class
of the element is dynamically applied, for instance
when updating the element's classList property directly. */
p:global(.big.red) {
/* applies to all <p> elements belonging to this component
with `class="big red"`, even if it is applied
programmatically (for example by a library) */
}
</style>
```
Expand All @@ -66,6 +63,30 @@ The `-global-` part will be removed when compiled, and the keyframe will then be
</style>
```

## :global

To apply styles to a group of selectors globally, create a `:global {...}` block:

```svelte
<style>
:global {
/* applies to every <div> in your application */
div { ... }

/* applies to every <p> in your application */
p { ... }
}

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

> The second example above could also be written as an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped, though the nested form is preferred.

## Nested style tags

There should only be 1 top-level `<style>` tag per component.
Expand Down
20 changes: 10 additions & 10 deletions packages/svelte/messages/compile-errors/style.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,35 @@

## css_global_block_invalid_combinator

> A :global {...} block cannot follow a %name% combinator
> A `:global` selector cannot follow a `%name%` combinator

## css_global_block_invalid_declaration

> A :global {...} block can only contain rules, not declarations
> A top-level `:global {...}` block can only contain rules, not declarations

## css_global_block_invalid_list

> A :global {...} block cannot be part of a selector list with more than one item
> A `:global` selector cannot be part of a selector list with more than one item

## css_global_block_invalid_modifier

> A :global {...} block cannot modify an existing selector
> A `:global` selector cannot modify an existing selector

## css_global_block_invalid_placement
## css_global_block_invalid_modifier_start

> A :global {...} block can only appear at the end of a selector sequence (did you mean to use :global(...) instead?)
> A `:global` selector can only be modified if it is a descendant of other selectors

## css_global_invalid_placement

> :global(...) can be at the start or end of a selector sequence, but not in the middle
> `:global(...)` can be at the start or end of a selector sequence, but not in the middle

## css_global_invalid_selector

> :global(...) must contain exactly one selector
> `:global(...)` must contain exactly one selector

## css_global_invalid_selector_list

> :global(...) must not contain type or universal selectors when used in a compound selector
> `:global(...)` must not contain type or universal selectors when used in a compound selector

## css_nesting_selector_invalid_placement

Expand All @@ -48,4 +48,4 @@

## css_type_selector_invalid_placement

> :global(...) must not be followed with a type selector
> `:global(...)` must not be followed by a type selector
38 changes: 19 additions & 19 deletions packages/svelte/src/compiler/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,76 +434,76 @@ export function css_expected_identifier(node) {
}

/**
* A :global {...} block cannot follow a %name% combinator
* A `:global` selector cannot follow a `%name%` combinator
* @param {null | number | NodeLike} node
* @param {string} name
* @returns {never}
*/
export function css_global_block_invalid_combinator(node, name) {
e(node, "css_global_block_invalid_combinator", `A :global {...} block cannot follow a ${name} combinator`);
e(node, "css_global_block_invalid_combinator", `A \`:global\` selector cannot follow a \`${name}\` combinator`);
}

/**
* A :global {...} block can only contain rules, not declarations
* A top-level `:global {...}` block can only contain rules, not declarations
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_block_invalid_declaration(node) {
e(node, "css_global_block_invalid_declaration", "A :global {...} block can only contain rules, not declarations");
e(node, "css_global_block_invalid_declaration", "A top-level `:global {...}` block can only contain rules, not declarations");
}

/**
* A :global {...} block cannot be part of a selector list with more than one item
* A `:global` selector cannot be part of a selector list with more than one item
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_block_invalid_list(node) {
e(node, "css_global_block_invalid_list", "A :global {...} block cannot be part of a selector list with more than one item");
e(node, "css_global_block_invalid_list", "A `:global` selector cannot be part of a selector list with more than one item");
}

/**
* A :global {...} block cannot modify an existing selector
* A `:global` selector cannot modify an existing selector
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_block_invalid_modifier(node) {
e(node, "css_global_block_invalid_modifier", "A :global {...} block cannot modify an existing selector");
e(node, "css_global_block_invalid_modifier", "A `:global` selector cannot modify an existing selector");
}

/**
* A :global {...} block can only appear at the end of a selector sequence (did you mean to use :global(...) instead?)
* A `:global` selector can only be modified if it is a descendant of other selectors
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_block_invalid_placement(node) {
e(node, "css_global_block_invalid_placement", "A :global {...} block can only appear at the end of a selector sequence (did you mean to use :global(...) instead?)");
export function css_global_block_invalid_modifier_start(node) {
e(node, "css_global_block_invalid_modifier_start", "A `:global` selector can only be modified if it is a descendant of other selectors");
}

/**
* :global(...) can be at the start or end of a selector sequence, but not in the middle
* `:global(...)` can be at the start or end of a selector sequence, but not in the middle
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_invalid_placement(node) {
e(node, "css_global_invalid_placement", ":global(...) can be at the start or end of a selector sequence, but not in the middle");
e(node, "css_global_invalid_placement", "`:global(...)` can be at the start or end of a selector sequence, but not in the middle");
}

/**
* :global(...) must contain exactly one selector
* `:global(...)` must contain exactly one selector
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_invalid_selector(node) {
e(node, "css_global_invalid_selector", ":global(...) must contain exactly one selector");
e(node, "css_global_invalid_selector", "`:global(...)` must contain exactly one selector");
}

/**
* :global(...) must not contain type or universal selectors when used in a compound selector
* `:global(...)` must not contain type or universal selectors when used in a compound selector
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_global_invalid_selector_list(node) {
e(node, "css_global_invalid_selector_list", ":global(...) must not contain type or universal selectors when used in a compound selector");
e(node, "css_global_invalid_selector_list", "`:global(...)` must not contain type or universal selectors when used in a compound selector");
}

/**
Expand All @@ -525,12 +525,12 @@ export function css_selector_invalid(node) {
}

/**
* :global(...) must not be followed with a type selector
* `:global(...)` must not be followed by a type selector
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function css_type_selector_invalid_placement(node) {
e(node, "css_type_selector_invalid_placement", ":global(...) must not be followed with a type selector");
e(node, "css_type_selector_invalid_placement", "`:global(...)` must not be followed by a type selector");
}

/**
Expand Down
Loading
Loading