Skip to content

Commit 50ff5c1

Browse files
authored
fix: skip descriptor validation for nestable at-rules (#362)
1 parent ff14a76 commit 50ff5c1

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/rules/no-invalid-at-rules.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ import { isSyntaxMatchError } from "../util.js";
2424
// Helpers
2525
//-----------------------------------------------------------------------------
2626

27+
/**
28+
* Set of at-rules that can be nested inside style rules.
29+
* @see https://www.w3.org/TR/css-nesting-1/#conditionals
30+
*/
31+
const nestableAtRules = new Set([
32+
"media",
33+
"supports",
34+
"layer",
35+
"scope",
36+
"container",
37+
"starting-style",
38+
]);
39+
2740
/**
2841
* A valid `@charset` rule must:
2942
* - Enclose the encoding name in double quotes
@@ -229,6 +242,10 @@ export default {
229242
sourceCode.getParent(sourceCode.getParent(node))
230243
);
231244

245+
if (nestableAtRules.has(atRule.name.toLowerCase())) {
246+
return;
247+
}
248+
232249
const { error } = lexer.matchAtruleDescriptor(
233250
atRule.name,
234251
node.property,

tests/rules/no-invalid-at-rules.test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ ruleTester.run("no-invalid-at-rules", rule, {
3333
'@charset "UTF-8";',
3434
'@charset "UTF-8"; @import url("foo.css");',
3535
"@media screen and (max-width: 600px) { body { font-size: 12px; } }",
36+
".foo { @media (max-width: 800px) { color: red; } }",
37+
".foo { @media (max-width: 800px) { color: red; background: blue; font-size: 16px; } }",
38+
".foo { @supports (display: grid) { display: grid; grid-template-columns: 1fr 1fr; } }",
39+
// TODO: Uncomment once https://github.com/eslint/csstree/issues/106 is fixed
40+
// ".foo { @layer base { color: red; } }",
41+
".foo { @scope (.card) { color: red; } }",
42+
".foo { @container (min-width: 700px) { color: red; } }",
43+
".foo { @starting-style { opacity: 0; transform: translateY(-10px); } }",
44+
".foo { @media (min-width: 768px) { color: red; @media (orientation: landscape) { background: blue; @supports (display: flex) { display: flex; } } } }",
45+
"@property --my-color { syntax: '<color>'; inherits: false; initial-value: #c0ffee; }",
46+
"@media (max-width: 800px) { .foo { color: red; } }",
47+
".foo { @media (max-width: 800px) { & .bar { color: red; } &:hover { background: blue; } } }",
48+
"@layer base { .foo { color: red; } }",
3649
{
3750
code: "@foobar url(foo.css) { body { font-size: 12px } }",
3851
languageOptions: {
@@ -173,6 +186,19 @@ ruleTester.run("no-invalid-at-rules", rule, {
173186
},
174187
],
175188
},
189+
{
190+
code: "@font-face { color: red; }",
191+
errors: [
192+
{
193+
messageId: "unknownDescriptor",
194+
data: { name: "font-face", descriptor: "color" },
195+
line: 1,
196+
column: 14,
197+
endLine: 1,
198+
endColumn: 19,
199+
},
200+
],
201+
},
176202
{
177203
code: "@property --foo { syntax: red; }",
178204
errors: [

0 commit comments

Comments
 (0)