Describe the bug
When using fallbackVar with an empty string as the fallback value (e.g. fallbackVar(myVar, "")), the generated CSS output drops the fallback entirely and produces var(--myVar) instead of the expected var(--myVar, ).
This breaks the intentional CSS pattern where an empty fallback (comma followed by nothing) allows the variable to be replaced by an empty value when the custom property is not defined. This technique is used in libraries like Tailwind CSS to implement optional inset effects (e.g., var(--inset,)).
Current behavior
import { createVar, fallbackVar, style } from '@vanilla-extract/css';
const inset = createVar();
const shadow = style({
boxShadow: `${fallbackVar(inset, "")} 0 0 0 3px red`,
});
Actual generated CSS:
.boxShadow {
box-shadow: var(--inset__abc123) 0 0 0 3px red;
}
Expected behavior
The empty string fallback should produce a trailing comma inside var() to represent an empty fallback value:
.boxShadow {
box-shadow: var(--inset__abc123, ) 0 0 0 3px red;
}
Root cause
The fallbackVar implementation currently filters out falsy values using .filter(Boolean) (see code). Since an empty string is falsy, it gets removed before generating the CSS variable function.
Proposed fix
Replace the falsy filter with a more precise check that only removes undefined (or null), while keeping "" and 0:
// current
const fallbackValues = [variable, ...fallbacks].filter(Boolean);
// proposed
const fallbackValues = [variable, ...fallbacks].filter(value => value !== undefined);
Alternatively, keep null filtering as well:
const fallbackValues = [variable, ...fallbacks].filter(value => value != null);
Workaround for users
Until this is fixed, a single space (" ") can be used as a non‑falsy placeholder that still results in an empty fallback in CSS:
const shadow = style({
boxShadow: `${fallbackVar(inset, " ")} 0 0 0 3px red`,
});
This generates var(--inset__abc123, ) ... as expected.
Reproduction
https://github.com/thep0y/vanilla-extract-css/blob/main/src/App.css.ts
System Info
System:
OS: Windows 11 10.0.26200
CPU: (16) x64 AMD Ryzen 7 8845H w/ Radeon 780M Graphics
Memory: 14.76 GB / 31.31 GB
Binaries:
Node: 22.18.0 - E:\Program Files\nodejs\node.EXE
npm: 10.9.3 - E:\Program Files\nodejs\npm.CMD
bun: 1.3.11 - E:\bin\bun.EXE
Browsers:
Chrome: 146.0.7680.178
Edge: Chromium (143.0.3650.96)
Internet Explorer: 11.0.26100.7309
npmPackages:
@vanilla-extract/css: ^1.20.1 => 1.20.1
@vanilla-extract/vite-plugin: ^5.2.2 => 5.2.2
vite: ^8.0.8 => 8.0.8
Used Package Manager
bun
Logs
Validations
Describe the bug
When using
fallbackVarwith an empty string as the fallback value (e.g.fallbackVar(myVar, "")), the generated CSS output drops the fallback entirely and producesvar(--myVar)instead of the expectedvar(--myVar, ).This breaks the intentional CSS pattern where an empty fallback (comma followed by nothing) allows the variable to be replaced by an empty value when the custom property is not defined. This technique is used in libraries like Tailwind CSS to implement optional
inseteffects (e.g.,var(--inset,)).Current behavior
Actual generated CSS:
Expected behavior
The empty string fallback should produce a trailing comma inside
var()to represent an empty fallback value:Root cause
The
fallbackVarimplementation currently filters out falsy values using.filter(Boolean)(see code). Since an empty string is falsy, it gets removed before generating the CSS variable function.Proposed fix
Replace the falsy filter with a more precise check that only removes
undefined(ornull), while keeping""and0:Alternatively, keep
nullfiltering as well:Workaround for users
Until this is fixed, a single space (
" ") can be used as a non‑falsy placeholder that still results in an empty fallback in CSS:This generates
var(--inset__abc123, ) ...as expected.Reproduction
https://github.com/thep0y/vanilla-extract-css/blob/main/src/App.css.ts
System Info
System: OS: Windows 11 10.0.26200 CPU: (16) x64 AMD Ryzen 7 8845H w/ Radeon 780M Graphics Memory: 14.76 GB / 31.31 GB Binaries: Node: 22.18.0 - E:\Program Files\nodejs\node.EXE npm: 10.9.3 - E:\Program Files\nodejs\npm.CMD bun: 1.3.11 - E:\bin\bun.EXE Browsers: Chrome: 146.0.7680.178 Edge: Chromium (143.0.3650.96) Internet Explorer: 11.0.26100.7309 npmPackages: @vanilla-extract/css: ^1.20.1 => 1.20.1 @vanilla-extract/vite-plugin: ^5.2.2 => 5.2.2 vite: ^8.0.8 => 8.0.8Used Package Manager
bun
Logs
Validations