Skip to content

Commit 997bf97

Browse files
committed
fix(css_formatter): correct spacing in container style queries
1 parent 92964a7 commit 997bf97

7 files changed

Lines changed: 169 additions & 83 deletions

File tree

.changeset/sixty-things-pump.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
Fixed [#6680](https://github.com/biomejs/biome/issues/6680):
5+
Biome incorrectly formatted container-style queries by inserting misplaced spaces.
6+
7+
```diff
8+
- @container style (--responsive: true) {}
9+
+ @container style(--responsive: true) {}
10+
```
11+

crates/biome_css_formatter/src/css/auxiliary/container_style_query_in_parens.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ impl FormatNodeRule<CssContainerStyleQueryInParens> for FormatCssContainerStyleQ
2121
f,
2222
[
2323
style_token.format(),
24-
space(),
2524
group(&format_args![
2625
l_paren_token.format(),
2726
soft_block_indent(&query.format()),

crates/biome_css_formatter/tests/specs/css/atrule/container.css.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ Quote style: Double Quotes
9898
@container my-layout (inline-size > 45em) {
9999
}
100100

101-
@container card (inline-size > 30em) or style (--responsive: true) {
101+
@container card (inline-size > 30em) or style(--responsive: true) {
102102
}
103-
@container card (inline-size > 30em) and style (--responsive: true) {
103+
@container card (inline-size > 30em) and style(--responsive: true) {
104104
}
105105

106-
@container card (inline-size > 30em) and style (--responsive: true) {
106+
@container card (inline-size > 30em) and style(--responsive: true) {
107107
}
108108

109109
@container (inline-size >= 0px) {
@@ -127,16 +127,16 @@ Quote style: Double Quotes
127127
@container sidebar (min-width: 400px) {
128128
}
129129

130-
@container test style (--responsive: true) {
130+
@container test style(--responsive: true) {
131131
}
132132

133-
@container style (--responsive: true) {
133+
@container style(--responsive: true) {
134134
}
135135

136136
@container card (inline-size > 30em) {
137137
}
138138

139-
@container style (--responsive: true) {
139+
@container style(--responsive: true) {
140140
}
141141

142142
@container (inline-size >= calc(200px)) {

crates/biome_css_parser/src/syntax/at_rule/container/mod.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,18 @@ pub(crate) fn parse_container_at_rule(p: &mut CssParser) -> ParsedSyntax {
7474

7575
p.bump(T![container]);
7676

77-
if parse_custom_identifier(p, CssLexContext::Regular)
78-
.ok()
79-
.is_none()
80-
{
77+
if !is_at_container_style_query_in_parens(p) {
78+
let name = parse_custom_identifier(p, CssLexContext::Regular);
8179
// Because the name is optional, we have to indirectly check if it's
8280
// a CSS-wide keyword that can't be used. If it was required, we could
8381
// use `.or_recover` or `.or_add_diagnostic` here instead.
84-
if p.cur().is_css_wide_keyword() {
82+
if name.is_absent() && p.cur().is_css_wide_keyword() {
8583
p.err_and_bump(
8684
expected_non_css_wide_keyword_identifier(p, p.cur_range()),
8785
CSS_BOGUS,
8886
)
8987
}
90-
};
88+
}
9189

9290
parse_any_container_query(p)
9391
.or_recover(p, &AnyQueryParseRecovery, expected_any_container_query)

crates/biome_css_parser/tests/css_test_suite/ok/at_rule/at_rule_container.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@
3434
@container --dashed-name not (width <= 500px) { }
3535

3636
@container name not style(color: red) {}
37+
38+
@container style (--responsive: true) { }

crates/biome_css_parser/tests/css_test_suite/ok/at_rule/at_rule_container.css.snap

Lines changed: 117 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ expression: snapshot
4242
4343
@container name not style(color: red) {}
4444
45+
@container style (--responsive: true) { }
46+
4547
```
4648

4749

@@ -436,19 +438,23 @@ CssRoot {
436438
at_token: AT@511..514 "@" [Newline("\n"), Newline("\n")] [],
437439
rule: CssContainerAtRule {
438440
container_token: CONTAINER_KW@514..524 "container" [] [Whitespace(" ")],
439-
name: CssCustomIdentifier {
440-
value_token: IDENT@524..529 "style" [] [],
441-
},
442-
query: CssContainerSizeFeatureInParens {
441+
name: missing (optional),
442+
query: CssContainerStyleQueryInParens {
443+
style_token: STYLE_KW@524..529 "style" [] [],
443444
l_paren_token: L_PAREN@529..530 "(" [] [],
444-
feature: CssQueryFeaturePlain {
445-
name: CssIdentifier {
446-
value_token: IDENT@530..542 "--responsive" [] [],
447-
},
448-
colon_token: COLON@542..544 ":" [] [Whitespace(" ")],
449-
value: CssIdentifier {
450-
value_token: IDENT@544..548 "true" [] [],
445+
query: CssDeclaration {
446+
property: CssGenericProperty {
447+
name: CssDashedIdentifier {
448+
value_token: IDENT@530..542 "--responsive" [] [],
449+
},
450+
colon_token: COLON@542..544 ":" [] [Whitespace(" ")],
451+
value: CssGenericComponentValueList [
452+
CssIdentifier {
453+
value_token: IDENT@544..548 "true" [] [],
454+
},
455+
],
451456
},
457+
important: missing (optional),
452458
},
453459
r_paren_token: R_PAREN@548..550 ")" [] [Whitespace(" ")],
454460
},
@@ -493,19 +499,23 @@ CssRoot {
493499
at_token: AT@597..600 "@" [Newline("\n"), Newline("\n")] [],
494500
rule: CssContainerAtRule {
495501
container_token: CONTAINER_KW@600..610 "container" [] [Whitespace(" ")],
496-
name: CssCustomIdentifier {
497-
value_token: IDENT@610..615 "style" [] [],
498-
},
499-
query: CssContainerSizeFeatureInParens {
502+
name: missing (optional),
503+
query: CssContainerStyleQueryInParens {
504+
style_token: STYLE_KW@610..615 "style" [] [],
500505
l_paren_token: L_PAREN@615..616 "(" [] [],
501-
feature: CssQueryFeaturePlain {
502-
name: CssIdentifier {
503-
value_token: IDENT@616..628 "--responsive" [] [],
504-
},
505-
colon_token: COLON@628..630 ":" [] [Whitespace(" ")],
506-
value: CssIdentifier {
507-
value_token: IDENT@630..634 "true" [] [],
506+
query: CssDeclaration {
507+
property: CssGenericProperty {
508+
name: CssDashedIdentifier {
509+
value_token: IDENT@616..628 "--responsive" [] [],
510+
},
511+
colon_token: COLON@628..630 ":" [] [Whitespace(" ")],
512+
value: CssGenericComponentValueList [
513+
CssIdentifier {
514+
value_token: IDENT@630..634 "true" [] [],
515+
},
516+
],
508517
},
518+
important: missing (optional),
509519
},
510520
r_paren_token: R_PAREN@634..636 ")" [] [Whitespace(" ")],
511521
},
@@ -684,17 +694,48 @@ CssRoot {
684694
},
685695
},
686696
},
697+
CssAtRule {
698+
at_token: AT@847..850 "@" [Newline("\n"), Newline("\n")] [],
699+
rule: CssContainerAtRule {
700+
container_token: CONTAINER_KW@850..860 "container" [] [Whitespace(" ")],
701+
name: missing (optional),
702+
query: CssContainerStyleQueryInParens {
703+
style_token: STYLE_KW@860..866 "style" [] [Whitespace(" ")],
704+
l_paren_token: L_PAREN@866..867 "(" [] [],
705+
query: CssDeclaration {
706+
property: CssGenericProperty {
707+
name: CssDashedIdentifier {
708+
value_token: IDENT@867..879 "--responsive" [] [],
709+
},
710+
colon_token: COLON@879..881 ":" [] [Whitespace(" ")],
711+
value: CssGenericComponentValueList [
712+
CssIdentifier {
713+
value_token: IDENT@881..885 "true" [] [],
714+
},
715+
],
716+
},
717+
important: missing (optional),
718+
},
719+
r_paren_token: R_PAREN@885..887 ")" [] [Whitespace(" ")],
720+
},
721+
block: CssRuleBlock {
722+
l_curly_token: L_CURLY@887..890 "{" [] [Whitespace(" ")],
723+
rules: CssRuleList [],
724+
r_curly_token: R_CURLY@890..891 "}" [] [],
725+
},
726+
},
727+
},
687728
],
688-
eof_token: EOF@847..848 "" [Newline("\n")] [],
729+
eof_token: EOF@891..892 "" [Newline("\n")] [],
689730
}
690731
```
691732

692733
## CST
693734

694735
```
695-
0: CSS_ROOT@0..848
736+
0: CSS_ROOT@0..892
696737
0: (empty)
697-
1: CSS_RULE_LIST@0..847
738+
1: CSS_RULE_LIST@0..891
698739
699740
0: [email protected] "@" [] []
700741
@@ -968,17 +1009,20 @@ CssRoot {
9681009
0: AT@511..514 "@" [Newline("\n"), Newline("\n")] []
9691010
1: CSS_CONTAINER_AT_RULE@514..554
9701011
0: CONTAINER_KW@514..524 "container" [] [Whitespace(" ")]
971-
1: CSS_CUSTOM_IDENTIFIER@524..529
972-
0: IDENT@524..529 "style" [] []
973-
2: CSS_CONTAINER_SIZE_FEATURE_IN_PARENS@529..550
974-
0: L_PAREN@529..530 "(" [] []
975-
1: CSS_QUERY_FEATURE_PLAIN@530..548
976-
0: CSS_IDENTIFIER@530..542
977-
0: IDENT@530..542 "--responsive" [] []
978-
1: COLON@542..544 ":" [] [Whitespace(" ")]
979-
2: CSS_IDENTIFIER@544..548
980-
0: IDENT@544..548 "true" [] []
981-
2: R_PAREN@548..550 ")" [] [Whitespace(" ")]
1012+
1: (empty)
1013+
2: CSS_CONTAINER_STYLE_QUERY_IN_PARENS@524..550
1014+
0: STYLE_KW@524..529 "style" [] []
1015+
1: L_PAREN@529..530 "(" [] []
1016+
2: CSS_DECLARATION@530..548
1017+
0: CSS_GENERIC_PROPERTY@530..548
1018+
0: CSS_DASHED_IDENTIFIER@530..542
1019+
0: IDENT@530..542 "--responsive" [] []
1020+
1: COLON@542..544 ":" [] [Whitespace(" ")]
1021+
2: CSS_GENERIC_COMPONENT_VALUE_LIST@544..548
1022+
0: CSS_IDENTIFIER@544..548
1023+
0: IDENT@544..548 "true" [] []
1024+
1: (empty)
1025+
3: R_PAREN@548..550 ")" [] [Whitespace(" ")]
9821026
3: CSS_RULE_BLOCK@550..554
9831027
0: L_CURLY@550..553 "{" [] [Whitespace(" ")]
9841028
1: CSS_RULE_LIST@553..553
@@ -1008,17 +1052,20 @@ CssRoot {
10081052
0: AT@597..600 "@" [Newline("\n"), Newline("\n")] []
10091053
1: CSS_CONTAINER_AT_RULE@600..640
10101054
0: CONTAINER_KW@600..610 "container" [] [Whitespace(" ")]
1011-
1: CSS_CUSTOM_IDENTIFIER@610..615
1012-
0: IDENT@610..615 "style" [] []
1013-
2: CSS_CONTAINER_SIZE_FEATURE_IN_PARENS@615..636
1014-
0: L_PAREN@615..616 "(" [] []
1015-
1: CSS_QUERY_FEATURE_PLAIN@616..634
1016-
0: CSS_IDENTIFIER@616..628
1017-
0: IDENT@616..628 "--responsive" [] []
1018-
1: COLON@628..630 ":" [] [Whitespace(" ")]
1019-
2: CSS_IDENTIFIER@630..634
1020-
0: IDENT@630..634 "true" [] []
1021-
2: R_PAREN@634..636 ")" [] [Whitespace(" ")]
1055+
1: (empty)
1056+
2: CSS_CONTAINER_STYLE_QUERY_IN_PARENS@610..636
1057+
0: STYLE_KW@610..615 "style" [] []
1058+
1: L_PAREN@615..616 "(" [] []
1059+
2: CSS_DECLARATION@616..634
1060+
0: CSS_GENERIC_PROPERTY@616..634
1061+
0: CSS_DASHED_IDENTIFIER@616..628
1062+
0: IDENT@616..628 "--responsive" [] []
1063+
1: COLON@628..630 ":" [] [Whitespace(" ")]
1064+
2: CSS_GENERIC_COMPONENT_VALUE_LIST@630..634
1065+
0: CSS_IDENTIFIER@630..634
1066+
0: IDENT@630..634 "true" [] []
1067+
1: (empty)
1068+
3: R_PAREN@634..636 ")" [] [Whitespace(" ")]
10221069
3: CSS_RULE_BLOCK@636..640
10231070
0: L_CURLY@636..639 "{" [] [Whitespace(" ")]
10241071
1: CSS_RULE_LIST@639..639
@@ -1140,6 +1187,28 @@ CssRoot {
11401187
0: L_CURLY@845..846 "{" [] []
11411188
1: CSS_RULE_LIST@846..846
11421189
2: R_CURLY@846..847 "}" [] []
1143-
2: EOF@847..848 "" [Newline("\n")] []
1190+
19: CSS_AT_RULE@847..891
1191+
0: AT@847..850 "@" [Newline("\n"), Newline("\n")] []
1192+
1: CSS_CONTAINER_AT_RULE@850..891
1193+
0: CONTAINER_KW@850..860 "container" [] [Whitespace(" ")]
1194+
1: (empty)
1195+
2: CSS_CONTAINER_STYLE_QUERY_IN_PARENS@860..887
1196+
0: STYLE_KW@860..866 "style" [] [Whitespace(" ")]
1197+
1: L_PAREN@866..867 "(" [] []
1198+
2: CSS_DECLARATION@867..885
1199+
0: CSS_GENERIC_PROPERTY@867..885
1200+
0: CSS_DASHED_IDENTIFIER@867..879
1201+
0: IDENT@867..879 "--responsive" [] []
1202+
1: COLON@879..881 ":" [] [Whitespace(" ")]
1203+
2: CSS_GENERIC_COMPONENT_VALUE_LIST@881..885
1204+
0: CSS_IDENTIFIER@881..885
1205+
0: IDENT@881..885 "true" [] []
1206+
1: (empty)
1207+
3: R_PAREN@885..887 ")" [] [Whitespace(" ")]
1208+
3: CSS_RULE_BLOCK@887..891
1209+
0: L_CURLY@887..890 "{" [] [Whitespace(" ")]
1210+
1: CSS_RULE_LIST@890..890
1211+
2: R_CURLY@890..891 "}" [] []
1212+
2: EOF@891..892 "" [Newline("\n")] []
11441213
11451214
```

crates/biome_css_parser/tests/css_test_suite/ok/at_rule/at_rule_container_complex.css.snap

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -592,19 +592,23 @@ CssRoot {
592592
at_token: AT@650..652 "@" [Newline("\n")] [],
593593
rule: CssContainerAtRule {
594594
container_token: CONTAINER_KW@652..662 "container" [] [Whitespace(" ")],
595-
name: CssCustomIdentifier {
596-
value_token: IDENT@662..667 "style" [] [],
597-
},
598-
query: CssContainerSizeFeatureInParens {
595+
name: missing (optional),
596+
query: CssContainerStyleQueryInParens {
597+
style_token: STYLE_KW@662..667 "style" [] [],
599598
l_paren_token: L_PAREN@667..668 "(" [] [],
600-
feature: CssQueryFeaturePlain {
601-
name: CssIdentifier {
602-
value_token: IDENT@668..682 "--accent-color" [] [],
603-
},
604-
colon_token: COLON@682..684 ":" [] [Whitespace(" ")],
605-
value: CssIdentifier {
606-
value_token: IDENT@684..688 "blue" [] [],
599+
query: CssDeclaration {
600+
property: CssGenericProperty {
601+
name: CssDashedIdentifier {
602+
value_token: IDENT@668..682 "--accent-color" [] [],
603+
},
604+
colon_token: COLON@682..684 ":" [] [Whitespace(" ")],
605+
value: CssGenericComponentValueList [
606+
CssIdentifier {
607+
value_token: IDENT@684..688 "blue" [] [],
608+
},
609+
],
607610
},
611+
important: missing (optional),
608612
},
609613
r_paren_token: R_PAREN@688..690 ")" [] [Whitespace(" ")],
610614
},
@@ -1656,17 +1660,20 @@ CssRoot {
16561660
0: AT@650..652 "@" [Newline("\n")] []
16571661
1: CSS_CONTAINER_AT_RULE@652..692
16581662
0: CONTAINER_KW@652..662 "container" [] [Whitespace(" ")]
1659-
1: CSS_CUSTOM_IDENTIFIER@662..667
1660-
0: IDENT@662..667 "style" [] []
1661-
2: CSS_CONTAINER_SIZE_FEATURE_IN_PARENS@667..690
1662-
0: L_PAREN@667..668 "(" [] []
1663-
1: CSS_QUERY_FEATURE_PLAIN@668..688
1664-
0: CSS_IDENTIFIER@668..682
1665-
0: IDENT@668..682 "--accent-color" [] []
1666-
1: COLON@682..684 ":" [] [Whitespace(" ")]
1667-
2: CSS_IDENTIFIER@684..688
1668-
0: IDENT@684..688 "blue" [] []
1669-
2: R_PAREN@688..690 ")" [] [Whitespace(" ")]
1663+
1: (empty)
1664+
2: CSS_CONTAINER_STYLE_QUERY_IN_PARENS@662..690
1665+
0: STYLE_KW@662..667 "style" [] []
1666+
1: L_PAREN@667..668 "(" [] []
1667+
2: CSS_DECLARATION@668..688
1668+
0: CSS_GENERIC_PROPERTY@668..688
1669+
0: CSS_DASHED_IDENTIFIER@668..682
1670+
0: IDENT@668..682 "--accent-color" [] []
1671+
1: COLON@682..684 ":" [] [Whitespace(" ")]
1672+
2: CSS_GENERIC_COMPONENT_VALUE_LIST@684..688
1673+
0: CSS_IDENTIFIER@684..688
1674+
0: IDENT@684..688 "blue" [] []
1675+
1: (empty)
1676+
3: R_PAREN@688..690 ")" [] [Whitespace(" ")]
16701677
3: CSS_RULE_BLOCK@690..692
16711678
0: L_CURLY@690..691 "{" [] []
16721679
1: CSS_RULE_LIST@691..691

0 commit comments

Comments
 (0)