Skip to content

fix: add cssMinify: false to all Vite configs to prevent light-dark() breakage - #623

Merged
cixzhang merged 1 commit into
mainfrom
navi/fix/lightningcss-light-dark-example-apps
Mar 15, 2026
Merged

fix: add cssMinify: false to all Vite configs to prevent light-dark() breakage#623
cixzhang merged 1 commit into
mainfrom
navi/fix/lightningcss-light-dark-example-apps

Conversation

@cixzhang

@cixzhang cixzhang commented Mar 15, 2026

Copy link
Copy Markdown
Contributor

Problem

Vite's default CSS minifier (LightningCSS) "lowers" the native CSS light-dark() function into --lightningcss-light / --lightningcss-dark polyfill variables. These polyfill variables are never initialized, so every XDS color token silently becomes empty — all theming breaks with no visible error.

This has bitten us 3 separate times across different Vite configs:

The root cause: setting lightningcssTargets on the StyleX plugin is not sufficient. Vite's build-phase CSS minifier runs independently from the StyleX plugin and still mangles light-dark() values in any CSS it processes (including pre-compiled dist CSS).

Fix

Add build: { cssMinify: false } to every Vite config that builds XDS packages. This is safe because XDS dist CSS is already minified.

Config changes

  • apps/example-vite/vite.config.ts — add cssMinify: false
  • apps/storybook/vite.config.ts — add cssMinify: false

Documentation changes

  • apps/example-vite/README.md — add LightningCSS as the Adding Code of Conduct file #1 gotcha entry, detailed explanation section, and update the inline Vite config example to include cssMinify: false
  • apps/example-nextjs/README.md — add awareness note (Next.js uses PostCSS so not directly affected, but warn about custom CSS minifiers)

The internal vibe-test configs (vite.config.ts, vite.config.preview.ts, vite.config.report.ts) already have cssMinify: false from the earlier fixes.


… breakage

LightningCSS lowers CSS light-dark() into polyfill variables
(--lightningcss-light/--lightningcss-dark) that are never initialized,
silently breaking all XDS theming colors. This has bitten us 3 separate
times (PRs #558, #566, #499) across different Vite configs.

Changes:
- apps/example-vite/vite.config.ts: add build.cssMinify: false
- apps/storybook/vite.config.ts: add build.cssMinify: false
- apps/example-vite/README.md: add lightningcss gotcha as top entry,
  detailed explanation section, and update inline config example
- apps/example-nextjs/README.md: add awareness note (Next.js uses
  PostCSS so not directly affected, but warn about custom minifiers)

Co-authored-by: Navi <navi@navibot.dev>
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Mar 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

No new or modified components detected.

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@xds/core 9.4KB 15.1KB 2.4KB

Accessibility Audit

Status: No accessibility violations detected.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

@cixzhang
cixzhang merged commit 2820ac7 into main Mar 15, 2026
13 checks passed
@cixzhang
cixzhang deleted the navi/fix/lightningcss-light-dark-example-apps branch March 15, 2026 02:05
cixzhang added a commit that referenced this pull request Mar 15, 2026
LightningCSS lowers light-dark() into --lightningcss-light/--lightningcss-dark
polyfill variables for older browsers. This polyfill actually works correctly
IF the color-scheme declaration is in the same CSS file — lightningcss injects
toggle variable initialization wherever it sees color-scheme. But when
light-dark() and color-scheme are in separate files (as with XDS, where
tokens are in xds.css but color-scheme is set by XDSTheme via StyleX),
the polyfill vars are used but never defined, breaking all colors.

Fix: include `color-scheme: light dark` in both xds.css and theme CSS
output so the polyfill is self-contained. This makes XDS CSS compatible
with any bundler that runs lightningcss regardless of target configuration.

This reverts the cssMinify: false workarounds from PR #623 and earlier
(PRs #558, #566) since they're no longer needed — the root cause is fixed.

Co-authored-by: Navi <navi@navibot.dev>
cixzhang added a commit that referenced this pull request Mar 15, 2026
LightningCSS lowers light-dark() into --lightningcss-light/--lightningcss-dark
polyfill variables for older browsers. This polyfill actually works correctly
IF the color-scheme declaration is in the same CSS file — lightningcss injects
toggle variable initialization wherever it sees color-scheme. But when
light-dark() and color-scheme are in separate files (as with XDS, where
tokens are in xds.css but color-scheme is set by XDSTheme via StyleX),
the polyfill vars are used but never defined, breaking all colors.

Fix: add `color-scheme: light dark` to:
- reset.css — on :where(html), the canonical place for the declaration.
  Every XDS app imports this first.
- build-css.mjs output (xds.css) — for consumers who import xds.css
  without reset.css
- build-theme.mjs output (theme.css) — for theme files containing
  light-dark() values

This makes XDS CSS compatible with any bundler that runs lightningcss
regardless of target configuration. Reverts the cssMinify: false
workarounds from PR #623 and earlier (PRs #558, #566).

Co-authored-by: Navi <navi@navibot.dev>
cixzhang added a commit that referenced this pull request Mar 15, 2026
LightningCSS lowers light-dark() into --lightningcss-light/--lightningcss-dark
polyfill variables for older browsers. This polyfill actually works correctly
IF the color-scheme declaration is in the same CSS file — lightningcss injects
toggle variable initialization wherever it sees color-scheme. But when
light-dark() and color-scheme are in separate files (as with XDS, where
tokens are in xds.css but color-scheme is set by XDSTheme via StyleX),
the polyfill vars are used but never defined, breaking all colors.

Fix: add `color-scheme: light dark` to:
- reset.css — on :where(html), the canonical place for the declaration.
  Every XDS app imports this first.
- build-css.mjs output (xds.css) — for consumers who import xds.css
  without reset.css
- build-theme.mjs output (theme.css) — for theme files containing
  light-dark() values

This makes XDS CSS compatible with any bundler that runs lightningcss
regardless of target configuration. Reverts the cssMinify: false
workarounds from PR #623 and earlier (PRs #558, #566).

Co-authored-by: Navi <navi@navibot.dev>
cixzhang added a commit that referenced this pull request Mar 15, 2026
LightningCSS lowers light-dark() into --lightningcss-light/--lightningcss-dark
polyfill variables for older browsers. This polyfill actually works correctly
IF the color-scheme declaration is in the same CSS file — lightningcss injects
toggle variable initialization wherever it sees color-scheme. But when
light-dark() and color-scheme are in separate files (as with XDS, where
tokens are in xds.css but color-scheme is set by XDSTheme via StyleX),
the polyfill vars are used but never defined, breaking all colors.

Fix: add `color-scheme: light dark` to:
- reset.css — on :where(html), the canonical place for the declaration.
  Every XDS app imports this first.
- build-css.mjs output (xds.css) — for consumers who import xds.css
  without reset.css
- build-theme.mjs output (theme.css) — for theme files containing
  light-dark() values

This makes XDS CSS compatible with any bundler that runs lightningcss
regardless of target configuration. Reverts the cssMinify: false
workarounds from PR #623 and earlier (PRs #558, #566).

Co-authored-by: Navi <navi@navibot.dev>
cixzhang added a commit that referenced this pull request Mar 15, 2026
LightningCSS lowers light-dark() into --lightningcss-light/--lightningcss-dark
polyfill variables for older browsers. This polyfill actually works correctly
IF the color-scheme declaration is in the same CSS file — lightningcss injects
toggle variable initialization wherever it sees color-scheme. But when
light-dark() and color-scheme are in separate files (as with XDS, where
tokens are in xds.css but color-scheme is set by XDSTheme via StyleX),
the polyfill vars are used but never defined, breaking all colors.

Fix: add `color-scheme: light dark` to:
- reset.css — on :where(html), the canonical place for the declaration.
  Every XDS app imports this first.
- build-css.mjs output (xds.css) — for consumers who import xds.css
  without reset.css
- build-theme.mjs output (theme.css) — for theme files containing
  light-dark() values

This makes XDS CSS compatible with any bundler that runs lightningcss
regardless of target configuration. Reverts the cssMinify: false
workarounds from PR #623 and earlier (PRs #558, #566).

Co-authored-by: Navi <navi@navibot.dev>
cixzhang added a commit that referenced this pull request Apr 26, 2026
… breakage (#623)

LightningCSS lowers CSS light-dark() into polyfill variables
(--lightningcss-light/--lightningcss-dark) that are never initialized,
silently breaking all XDS theming colors. This has bitten us 3 separate
times (PRs #558, #566, #499) across different Vite configs.

Changes:
- apps/example-vite/vite.config.ts: add build.cssMinify: false
- apps/storybook/vite.config.ts: add build.cssMinify: false
- apps/example-vite/README.md: add lightningcss gotcha as top entry,
  detailed explanation section, and update inline config example
- apps/example-nextjs/README.md: add awareness note (Next.js uses
  PostCSS so not directly affected, but warn about custom minifiers)

Co-authored-by: Navi <navi@users.noreply.github.com>
cixzhang added a commit that referenced this pull request Jun 21, 2026
… breakage (#623)

LightningCSS lowers CSS light-dark() into polyfill variables
(--lightningcss-light/--lightningcss-dark) that are never initialized,
silently breaking all XDS theming colors. This has bitten us 3 separate
times (PRs #558, #566, #499) across different Vite configs.

Changes:
- apps/example-vite/vite.config.ts: add build.cssMinify: false
- apps/storybook/vite.config.ts: add build.cssMinify: false
- apps/example-vite/README.md: add lightningcss gotcha as top entry,
  detailed explanation section, and update inline config example
- apps/example-nextjs/README.md: add awareness note (Next.js uses
  PostCSS so not directly affected, but warn about custom minifiers)

Co-authored-by: Navi <navi@users.noreply.github.com>
cixzhang added a commit that referenced this pull request Jun 21, 2026
… breakage (#623)

LightningCSS lowers CSS light-dark() into polyfill variables
(--lightningcss-light/--lightningcss-dark) that are never initialized,
silently breaking all XDS theming colors. This has bitten us 3 separate
times (PRs #558, #566, #499) across different Vite configs.

Changes:
- apps/example-vite/vite.config.ts: add build.cssMinify: false
- apps/storybook/vite.config.ts: add build.cssMinify: false
- apps/example-vite/README.md: add lightningcss gotcha as top entry,
  detailed explanation section, and update inline config example
- apps/example-nextjs/README.md: add awareness note (Next.js uses
  PostCSS so not directly affected, but warn about custom minifiers)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant