Skip to content

Commit 1a9d8a5

Browse files
authored
fix: allow & to appear at the top when inside a :global(...) (#13215)
It's a valid CSS rule, which means "select the scope root": https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector#using_outside_nested_rule
1 parent 61d5195 commit 1a9d8a5

File tree

5 files changed

+41
-4
lines changed

5 files changed

+41
-4
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
4141
## css_nesting_selector_invalid_placement
4242

43-
> Nesting selectors can only be used inside a rule
43+
> Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`
4444
4545
## css_selector_invalid
4646

packages/svelte/src/compiler/errors.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,12 @@ export function css_global_invalid_selector_list(node) {
536536
}
537537

538538
/**
539-
* Nesting selectors can only be used inside a rule
539+
* Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`
540540
* @param {null | number | NodeLike} node
541541
* @returns {never}
542542
*/
543543
export function css_nesting_selector_invalid_placement(node) {
544-
e(node, "css_nesting_selector_invalid_placement", "Nesting selectors can only be used inside a rule");
544+
e(node, "css_nesting_selector_invalid_placement", "Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`");
545545
}
546546

547547
/**

packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,18 @@ const css_visitors = {
222222
const parent_rule = rule.metadata.parent_rule;
223223

224224
if (!parent_rule) {
225-
e.css_nesting_selector_invalid_placement(node);
225+
// https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector#using_outside_nested_rule
226+
const children = rule.prelude.children;
227+
const selectors = children[0].children[0].selectors;
228+
if (
229+
children.length > 1 ||
230+
selectors.length > 1 ||
231+
selectors[0].type !== 'PseudoClassSelector' ||
232+
selectors[0].name !== 'global' ||
233+
selectors[0].args?.children[0]?.children[0].selectors[0] !== node
234+
) {
235+
e.css_nesting_selector_invalid_placement(node);
236+
}
226237
} else if (
227238
// :global { &.foo { ... } } is invalid
228239
parent_rule.metadata.is_global_block &&
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'css_nesting_selector_invalid_placement',
6+
message:
7+
'Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`',
8+
position: [151, 152]
9+
}
10+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<style>
2+
/* valid */
3+
:global(&) {
4+
color: blue;
5+
}
6+
:global(& div) {
7+
color: blue;
8+
}
9+
:global(&) div {
10+
color: blue;
11+
}
12+
/* error */
13+
:global(div &) {
14+
color: blue;
15+
}
16+
</style>

0 commit comments

Comments
 (0)