<!doctype html> <title>Serialization of declarations in group rules</title> <link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7850"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style id="test-sheet"></style> <script> function serialize(cssText) { let [ss] = document.styleSheets; while (ss.rules.length) { ss.removeRule(0) } ss.insertRule(cssText); return ss.rules[0].cssText; } function assert_unchanged(cssText, description) { test(() => { assert_equals(serialize(cssText), cssText, description); }, description); } function assert_becomes(cssText, serializedCssText, description) { test(() => { assert_equals(serialize(cssText), serializedCssText, description); }, description); } assert_unchanged( "@media screen {\n div { color: red; background-color: green; }\n}", "Declarations are serialized on one line, rules on two." ) assert_becomes( "div { @media screen { color: red; background-color: green; } }", "div {\n @media screen {\n & { color: red; background-color: green; }\n}\n}", "Mixed declarations/rules are on two lines." ); assert_becomes( "div {\n @supports selector(&) { color: red; background-color: green; } &:hover { color: navy; } }", "div {\n @supports selector(&) {\n & { color: red; background-color: green; }\n}\n &:hover { color: navy; }\n}", "Implicit rule is serialized", ); assert_unchanged("div {\n @media screen {\n & { color: red; }\n}\n}", "Implicit rule not removed"); assert_becomes( "div { @media screen { & { color: red; &:hover { } } }", "div {\n @media screen {\n & {\n color: red;\n &:hover { }\n}\n}\n}", "Implicit + empty hover rule" ); assert_becomes( "div { @media screen { &.cls { color: red; } & { color: red; }", "div {\n @media screen {\n &.cls { color: red; }\n & { color: red; }\n}\n}", "Implicit like rule not in first position" ); assert_becomes( "div { @media screen { & { color: red; } & { color: red; }", "div {\n @media screen {\n & { color: red; }\n & { color: red; }\n}\n}", "Two implicit-like rules" ); assert_becomes( "div { @media screen { color: red; & { color: red; }", "div {\n @media screen {\n & { color: red; }\n & { color: red; }\n}\n}", "Implicit like rule after decls" ); assert_becomes( "div { @media screen { color: red; & { color: blue; }", "div {\n @media screen {\n & { color: red; }\n & { color: blue; }\n}\n}", "Implicit like rule after decls, missing closing braces" ); assert_becomes( "div { @media screen { &, p > & { color: blue; }", "div {\n @media screen {\n &, p > & { color: blue; }\n}\n}", "Implicit like rule with other selectors" ); assert_becomes( "div { & { color: red; } }", "div {\n & { color: red; }\n}", "Implicit-like rule in style rule" ); // Empty rules (confusingly?) serialize different between style rules // and conditional group rules. assert_unchanged("@media screen {\n}", "Empty conditional rule"); assert_unchanged("div { }", "Empty style rule"); assert_unchanged("div {\n @media screen {\n}\n}", "Empty conditional inside style rule"); assert_unchanged("@media screen {\n div { }\n}", "Empty style inside conditional"); </script>