Skip to content

Commit 13d86e9

Browse files
feat: allow :global in more places (alternative) (#12560)
* `div { :global { &.x { ... } } }` is equivalent to `div:global.x { ... }`, so the latter should be allowed, too * finalize * replace obsolete breaking change (which turned out to be a wrong change and was since reverted), add new breaking change note * changeset * regenerate types * Update sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md Co-authored-by: Rich Harris <[email protected]> * always remove descendant selector before global * error on lone `:global` with nested `&`, revert "remove spaces" rule * regenerate types * documentation * oops * switch to removing descendant combinator * fix * revert combinator validation relaxation * error on first global being modified * tweak docs * tweak error messages * Update documentation/docs/02-template-syntax/05-styles-and-classes.md Co-authored-by: Rich Harris <[email protected]> * clarify * tweak messages * update tests * tweak docs * tweak `:global(...)` docs * tweak docs --------- Co-authored-by: Rich Harris <[email protected]>
1 parent e2f17c8 commit 13d86e9

File tree

43 files changed

+483
-142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+483
-142
lines changed

.changeset/tricky-balloons-care.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: allow `:global` in more places

documentation/docs/02-template-syntax/05-styles-and-classes.md

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,28 @@ This works by adding a class to affected elements, which is based on a hash of t
2525
</style>
2626
```
2727

28-
## :global
28+
## :global(...)
2929

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

3232
```svelte
3333
<style>
3434
:global(body) {
35-
/* this will apply to <body> */
35+
/* applies to <body> */
3636
margin: 0;
3737
}
3838
3939
div :global(strong) {
40-
/* this will apply to all <strong> elements, in any
41-
component, that are inside <div> elements belonging
42-
to this component */
40+
/* applies to all <strong> elements, in any component,
41+
that are inside <div> elements belonging
42+
to this component */
4343
color: goldenrod;
4444
}
4545
46-
p:global(.red) {
47-
/* this will apply to all <p> elements belonging to this
48-
component with a class of red, even if class="red" does
49-
not initially appear in the markup, and is instead
50-
added at runtime. This is useful when the class
51-
of the element is dynamically applied, for instance
52-
when updating the element's classList property directly. */
46+
p:global(.big.red) {
47+
/* applies to all <p> elements belonging to this component
48+
with `class="big red"`, even if it is applied
49+
programmatically (for example by a library) */
5350
}
5451
</style>
5552
```
@@ -66,6 +63,30 @@ The `-global-` part will be removed when compiled, and the keyframe will then be
6663
</style>
6764
```
6865

66+
## :global
67+
68+
To apply styles to a group of selectors globally, create a `:global {...}` block:
69+
70+
```svelte
71+
<style>
72+
:global {
73+
/* applies to every <div> in your application */
74+
div { ... }
75+
76+
/* applies to every <p> in your application */
77+
p { ... }
78+
}
79+
80+
.a :global {
81+
/* applies to every `.b .c .d` element, in any component,
82+
that is inside an `.a` element in this component */
83+
.b .c .d {...}
84+
}
85+
</style>
86+
```
87+
88+
> 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.
89+
6990
## Nested style tags
7091

7192
There should only be 1 top-level `<style>` tag per component.

packages/svelte/messages/compile-errors/style.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,35 @@
88
99
## css_global_block_invalid_combinator
1010

11-
> A :global {...} block cannot follow a %name% combinator
11+
> A `:global` selector cannot follow a `%name%` combinator
1212
1313
## css_global_block_invalid_declaration
1414

15-
> A :global {...} block can only contain rules, not declarations
15+
> A top-level `:global {...}` block can only contain rules, not declarations
1616
1717
## css_global_block_invalid_list
1818

19-
> A :global {...} block cannot be part of a selector list with more than one item
19+
> A `:global` selector cannot be part of a selector list with more than one item
2020
2121
## css_global_block_invalid_modifier
2222

23-
> A :global {...} block cannot modify an existing selector
23+
> A `:global` selector cannot modify an existing selector
2424
25-
## css_global_block_invalid_placement
25+
## css_global_block_invalid_modifier_start
2626

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

31-
> :global(...) can be at the start or end of a selector sequence, but not in the middle
31+
> `:global(...)` can be at the start or end of a selector sequence, but not in the middle
3232
3333
## css_global_invalid_selector
3434

35-
> :global(...) must contain exactly one selector
35+
> `:global(...)` must contain exactly one selector
3636
3737
## css_global_invalid_selector_list
3838

39-
> :global(...) must not contain type or universal selectors when used in a compound selector
39+
> `:global(...)` must not contain type or universal selectors when used in a compound selector
4040
4141
## css_nesting_selector_invalid_placement
4242

@@ -48,4 +48,4 @@
4848
4949
## css_type_selector_invalid_placement
5050

51-
> :global(...) must not be followed with a type selector
51+
> `:global(...)` must not be followed by a type selector

packages/svelte/src/compiler/errors.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -434,76 +434,76 @@ export function css_expected_identifier(node) {
434434
}
435435

436436
/**
437-
* A :global {...} block cannot follow a %name% combinator
437+
* A `:global` selector cannot follow a `%name%` combinator
438438
* @param {null | number | NodeLike} node
439439
* @param {string} name
440440
* @returns {never}
441441
*/
442442
export function css_global_block_invalid_combinator(node, name) {
443-
e(node, "css_global_block_invalid_combinator", `A :global {...} block cannot follow a ${name} combinator`);
443+
e(node, "css_global_block_invalid_combinator", `A \`:global\` selector cannot follow a \`${name}\` combinator`);
444444
}
445445

446446
/**
447-
* A :global {...} block can only contain rules, not declarations
447+
* A top-level `:global {...}` block can only contain rules, not declarations
448448
* @param {null | number | NodeLike} node
449449
* @returns {never}
450450
*/
451451
export function css_global_block_invalid_declaration(node) {
452-
e(node, "css_global_block_invalid_declaration", "A :global {...} block can only contain rules, not declarations");
452+
e(node, "css_global_block_invalid_declaration", "A top-level `:global {...}` block can only contain rules, not declarations");
453453
}
454454

455455
/**
456-
* A :global {...} block cannot be part of a selector list with more than one item
456+
* A `:global` selector cannot be part of a selector list with more than one item
457457
* @param {null | number | NodeLike} node
458458
* @returns {never}
459459
*/
460460
export function css_global_block_invalid_list(node) {
461-
e(node, "css_global_block_invalid_list", "A :global {...} block cannot be part of a selector list with more than one item");
461+
e(node, "css_global_block_invalid_list", "A `:global` selector cannot be part of a selector list with more than one item");
462462
}
463463

464464
/**
465-
* A :global {...} block cannot modify an existing selector
465+
* A `:global` selector cannot modify an existing selector
466466
* @param {null | number | NodeLike} node
467467
* @returns {never}
468468
*/
469469
export function css_global_block_invalid_modifier(node) {
470-
e(node, "css_global_block_invalid_modifier", "A :global {...} block cannot modify an existing selector");
470+
e(node, "css_global_block_invalid_modifier", "A `:global` selector cannot modify an existing selector");
471471
}
472472

473473
/**
474-
* A :global {...} block can only appear at the end of a selector sequence (did you mean to use :global(...) instead?)
474+
* A `:global` selector can only be modified if it is a descendant of other selectors
475475
* @param {null | number | NodeLike} node
476476
* @returns {never}
477477
*/
478-
export function css_global_block_invalid_placement(node) {
479-
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?)");
478+
export function css_global_block_invalid_modifier_start(node) {
479+
e(node, "css_global_block_invalid_modifier_start", "A `:global` selector can only be modified if it is a descendant of other selectors");
480480
}
481481

482482
/**
483-
* :global(...) can be at the start or end of a selector sequence, but not in the middle
483+
* `:global(...)` can be at the start or end of a selector sequence, but not in the middle
484484
* @param {null | number | NodeLike} node
485485
* @returns {never}
486486
*/
487487
export function css_global_invalid_placement(node) {
488-
e(node, "css_global_invalid_placement", ":global(...) can be at the start or end of a selector sequence, but not in the middle");
488+
e(node, "css_global_invalid_placement", "`:global(...)` can be at the start or end of a selector sequence, but not in the middle");
489489
}
490490

491491
/**
492-
* :global(...) must contain exactly one selector
492+
* `:global(...)` must contain exactly one selector
493493
* @param {null | number | NodeLike} node
494494
* @returns {never}
495495
*/
496496
export function css_global_invalid_selector(node) {
497-
e(node, "css_global_invalid_selector", ":global(...) must contain exactly one selector");
497+
e(node, "css_global_invalid_selector", "`:global(...)` must contain exactly one selector");
498498
}
499499

500500
/**
501-
* :global(...) must not contain type or universal selectors when used in a compound selector
501+
* `:global(...)` must not contain type or universal selectors when used in a compound selector
502502
* @param {null | number | NodeLike} node
503503
* @returns {never}
504504
*/
505505
export function css_global_invalid_selector_list(node) {
506-
e(node, "css_global_invalid_selector_list", ":global(...) must not contain type or universal selectors when used in a compound selector");
506+
e(node, "css_global_invalid_selector_list", "`:global(...)` must not contain type or universal selectors when used in a compound selector");
507507
}
508508

509509
/**
@@ -525,12 +525,12 @@ export function css_selector_invalid(node) {
525525
}
526526

527527
/**
528-
* :global(...) must not be followed with a type selector
528+
* `:global(...)` must not be followed by a type selector
529529
* @param {null | number | NodeLike} node
530530
* @returns {never}
531531
*/
532532
export function css_type_selector_invalid_placement(node) {
533-
e(node, "css_type_selector_invalid_placement", ":global(...) must not be followed with a type selector");
533+
e(node, "css_type_selector_invalid_placement", "`:global(...)` must not be followed by a type selector");
534534
}
535535

536536
/**

0 commit comments

Comments
 (0)