[css-variables] Custom props with invalid var() should behave as 'unset'
We currently have a (WPT-enforced) bug where custom properties that
reference guaranteed-invalid values [1] behave themselves as guaranteed-
invalid. This is not correct per spec, which requires the custom
property to behave as 'unset' in this case. This was clarified in [2],
although the spec has described this behavior long before that.
Unfortunately Firefox has the same issue. Safari on the other hand, does
implement it correctly.
[1] https://drafts.csswg.org/css-variables/#guaranteed-invalid
[2] https://github.com/w3c/csswg-drafts/issues/4075
Bug: 980930
Change-Id: I84a0da3aad6b72b574009d560eb868632769098a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2108026
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751636}
diff --git a/css/css-env/env-in-custom-properties.tentative.html b/css/css-env/env-in-custom-properties.tentative.html
index ea471b0..6dadcc5 100644
--- a/css/css-env/env-in-custom-properties.tentative.html
+++ b/css/css-env/env-in-custom-properties.tentative.html
@@ -6,18 +6,30 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
- body {
+ #parent {
+ --var1: inherited;
+ }
+ #child {
--my-width: env(test, 100px);
width: var(--my-width);
+ --var1: env(nonexistent);
}
</style>
</head>
<body>
+ <div id="parent">
+ <div id="child"></div>
+ </div>
<script>
test(() => {
- const style = window.getComputedStyle(document.body);
+ const style = window.getComputedStyle(child);
assert_equals(style.getPropertyValue("width"), "100px");
- });
+ }, 'env() is substituted into a custom property');
+
+ test(() => {
+ const style = window.getComputedStyle(child);
+ assert_equals(style.getPropertyValue("--var1"), " inherited");
+ }, 'Substitution of unrecognized env() causes unset');
</script>
</body>
</html>
diff --git a/css/css-variables/variable-substitution-variable-declaration.html b/css/css-variables/variable-substitution-variable-declaration.html
index 0b0ab1f..678d05a 100644
--- a/css/css-variables/variable-substitution-variable-declaration.html
+++ b/css/css-variables/variable-substitution-variable-declaration.html
@@ -140,7 +140,7 @@
{ element: "target10", propertyName: "--varA", expectedPropertyValue: "" },
{ element: "target10", propertyName: "--varB", expectedPropertyValue: "" },
- { element: "target10", propertyName: "--varC", expectedPropertyValue: "" },
+ { element: "target10", propertyName: "--varC", expectedPropertyValue: " another good one" },
];
testcases.forEach(function (testcase) {
diff --git a/css/css-variables/variables-substitute-guaranteed-invalid.html b/css/css-variables/variables-substitute-guaranteed-invalid.html
new file mode 100644
index 0000000..c30e874
--- /dev/null
+++ b/css/css-variables/variables-substitute-guaranteed-invalid.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>Testing substitution of guaranteed-invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-variables/#guaranteed-invalid">
+<link rel="help" href="https://drafts.csswg.org/css-variables/#cycles">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #target1 {
+ /* Cycle */
+ --var1: var(--var2);
+ --var2: var(--var1);
+
+ /* Reference to cycle */
+ --var3: var(--var1);
+
+ /* Reference to non-existent property */
+ --var4: var(--noexist);
+ }
+
+ #target1parent {
+ --var3: inherited;
+ --var4: inherited;
+ }
+</style>
+<div id="target1parent">
+ <div id="target1"></div>
+</div>
+<script>
+ test( function () {
+ let cs = getComputedStyle(target1);
+ assert_equals(cs.getPropertyValue('--var1'), '');
+ assert_equals(cs.getPropertyValue('--var2'), '');
+ }, 'Custom properties in a cycle are guaranteed-invalid');
+
+ test( function () {
+ let cs = getComputedStyle(target1);
+ assert_equals(cs.getPropertyValue('--var3'), ' inherited');
+ }, 'A custom property referencing a cycle is treated as unset');
+
+ test( function () {
+ let cs = getComputedStyle(target1);
+ assert_equals(cs.getPropertyValue('--var4'), ' inherited');
+ }, 'A custom property referencing a non-existent variable is treated as unset');
+</script>