Repository: sveltejs/svelte (JavaScript)
Date: 2022-02-22 17:05:52+00:00
Task type: Bug Fix

Issue:
whitespace and !important token valid in css custom properties but not in svelte
### Describe the bug

```
h1 {
  --foo: ;
  color: var(--foo) blue;
}
	
h2 {
  --foo: !important;
  color: green var(--foo);
}
```
When I read this article [The CSS Custom Property Toggle Trick](https://css-tricks.com/the-css-custom-property-toggle-trick/), I am trying to use whitespace in css custom properties with svetle, it say "invalid value", but it should be valid according to W3C custom properties specification.

**Ref:** [https://www.w3.org/TR/css-variables-1/#syntax](https://www.w3.org/TR/css-variables-1/#syntax)
<img width="822" alt="Screenshot 2565-01-16 at 18 01 19" src="https://user-images.githubusercontent.com/1311673/149657235-5d8f6606-4aa2-4ceb-a948-b8f5721217c3.png">
<img width="785" alt="Screenshot 2565-01-16 at 18 06 53" src="https://user-images.githubusercontent.com/1311673/149657412-e47c376a-54c9-4753-ab57-00e43c2b2aa6.png">


### Reproduction

[svelte REPL: https://svelte.dev/repl/d563fcb1d63e405da8a74ae1ef8f30ad?version=3.46.2](https://svelte.dev/repl/d563fcb1d63e405da8a74ae1ef8f30ad?version=3.46.2)
[codepen: https://codepen.io/tanangular/pen/rNGPgRa](https://codepen.io/tanangular/pen/rNGPgRa)


![svelte-invalid](https://user-images.githubusercontent.com/1311673/149657956-d3cb827b-6869-40f0-8c29-f3ed34ce638c.jpg)

![whitespace](https://user-images.githubusercontent.com/1311673/149657960-f1100aa6-bd1f-4f57-8c49-3eff21cb2b91.jpg)




### Logs

_No response_

### System Info

```shell
System:
    OS: macOS 12.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 360.45 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 17.3.0 - ~/.nvm/versions/node/v17.3.0/bin/node
    npm: 8.3.0 - ~/.nvm/versions/node/v17.3.0/bin/npm
  Browsers:
    Chrome: 97.0.4692.71
    Chrome Canary: 99.0.4828.0
    Edge: 93.0.961.47
    Firefox: 96.0
    Safari: 15.2
    Safari Technology Preview: 15.4
  npmPackages:
    rollup: ^2.3.4 => 2.64.0 
    svelte: ^3.0.0 => 3.46.2
```


### Severity

annoyance


Issue discussion:
This is just memo but it works well on Firefox.

![image](https://user-images.githubusercontent.com/19153718/149660667-85c3c5a2-4ff8-4904-a761-3a561c07a572.png)

@baseballyama, thanks you, you 're right.
This bug has gone on
- Firefox 96.0.1 ✅
- Safari 15.2 (17612.3.6.1.6) ✅
- Safari Technology Preview Release 137 (Safari 15.4, WebKit 17613.1.11.8) ✅
- Google Chome Canary  99.0.4828.0  ✅

but still have a bug on
- Google Chrome Version 97.0.4692.71 ❌
- Microsoft Edge Version 97.0.1072.62 ❌
I think this is a browser bug. Svelte minifies `--foo: ;` to `--foo:;`, which _should_ be the same, per [the spec](https://www.w3.org/TR/css-variables-1/#changes-20151203). However, Chrome treats `--foo:;` as invalid. This was recently [fixed](https://bugs.chromium.org/p/chromium/issues/detail?id=1220149), and your REPL does work in Chrome Canary (v99).

![REPL linked above, with both the headings the correct color](https://user-images.githubusercontent.com/4992896/149831266-3639c311-b0e7-498a-b454-d0af96865a58.png)



Just reposting my comment from https://github.com/sveltejs/svelte/issues/7288#issuecomment-1046039821:

---

Looks like the change to the spec that makes `--foo:;` and `--foo: ;` equivalent is quite recent (in terms of spec changes anyways).

Personally I think it would be best to change this in Svelte regardless for better compatibility, it's a change lots of other tools have had to make as well since historically `--foo:;` and `--foo: ;` were not equivalent.

This is what the spec said last time I looked a couple of months ago:

> Note: While must represent at least one token, that one token may be whitespace. This implies that `--foo: ;` is valid, and the corresponding `var(--foo)` call would have a single space as its substitution value, but `--foo:;` is invalid.

...so I wouldn't be surprised if this sneaky problem shows up a lot for a while. It'll be a while before Electron is on 99 for example I bet.

Solution patch:
diff --git a/src/compiler/compile/css/Stylesheet.ts b/src/compiler/compile/css/Stylesheet.ts
--- a/src/compiler/compile/css/Stylesheet.ts
+++ b/src/compiler/compile/css/Stylesheet.ts
@@ -145,6 +145,10 @@ class Declaration {
 			? this.node.value.children[0]
 			: this.node.value;
 
+		// Don't minify whitespace in custom properties, since some browsers (Chromium < 99)
+		// treat --foo: ; and --foo:; differently
+		if (first.type === 'Raw' && /^\s+$/.test(first.value)) return;
+
 		let start = first.start;
 		while (/\s/.test(code.original[start])) start += 1;
 


Test patch:
diff --git a/test/css/samples/css-vars/expected.css b/test/css/samples/css-vars/expected.css
--- a/test/css/samples/css-vars/expected.css
+++ b/test/css/samples/css-vars/expected.css
@@ -1 +1 @@
-:root{--root-test:20}div.svelte-xyz{--test:10}
\ No newline at end of file
+:root{--root-test:20}div.svelte-xyz{--test:10}div.svelte-xyz{--foo: ;--bar: !important}
\ No newline at end of file
diff --git a/test/css/samples/css-vars/input.svelte b/test/css/samples/css-vars/input.svelte
--- a/test/css/samples/css-vars/input.svelte
+++ b/test/css/samples/css-vars/input.svelte
@@ -7,4 +7,9 @@
 	div {
 		--test: 10;
 	}
+
+	div {
+		--foo: ;
+		--bar: !important;
+	}
 </style>