Skip to content

fallbackVar discards empty string ("") as fallback, preventing CSS var() empty fallback pattern #1724

@thep0y

Description

@thep0y

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue is caused by a bug in a Vanilla Extract packagecssIssue related to the core css package

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions