Skip to content

fix: coerce NaN Lab/OKLab channels to 0 in parseColor#351

Open
sarathfrancis90 wants to merge 1 commit into
nativewind:mainfrom
sarathfrancis90:fix-color-mix-nan-channels
Open

fix: coerce NaN Lab/OKLab channels to 0 in parseColor#351
sarathfrancis90 wants to merge 1 commit into
nativewind:mainfrom
sarathfrancis90:fix-color-mix-nan-channels

Conversation

@sarathfrancis90

Copy link
Copy Markdown

Summary

Fixes #317.

color-mix() is resolved at compile time by lightningcss. For a degenerate
mix the result can have NaN chromaticity channels — mixing #000 with
transparent in oklab gives oklab(0 NaN NaN / 0.5), because black has no
chromaticity to interpolate. parseColor passed those NaN coords straight
to colorjs.io, which serialized them to "#NaNNaNNaN80". React Native
silently discards an invalid color string, so utilities like Tailwind's
bg-black/50 rendered with no background.

Fix

The lab/lch/oklab/oklch cases in parseColor (src/compiler/declarations.ts)
now coerce each channel through a small nanToZero helper. A missing color
component is 0 per CSS Color 4, so oklab(0 NaN NaN / 0.5) becomes
oklab(0 0 0 / 0.5) = black at 50% alpha, serializing to #00000080.

Testing

Added a regression test in src/__tests__/native/color-mix.test.tsx for
color-mix(in oklab, #000 50%, transparent). It fails on main
(Received "#NaNNaNNaN80") and passes with the fix ("#00000080").

yarn test, yarn typecheck and yarn lint all pass.

@danstepanov danstepanov force-pushed the fix-color-mix-nan-channels branch from 1e98225 to 3148e17 Compare June 20, 2026 05:32
@danstepanov

Copy link
Copy Markdown
Member

@sarathfrancis90 thanks for opening a PR, can you rebase with the main branch?

@sarathfrancis90 sarathfrancis90 force-pushed the fix-color-mix-nan-channels branch from 3148e17 to 08dfca1 Compare June 26, 2026 06:02
@sarathfrancis90

Copy link
Copy Markdown
Author

Rebased onto main — should be clean now. Thanks!

@danstepanov danstepanov added the v5 stability Tracking v5 stability for @latest release label Jul 8, 2026
@danstepanov

Copy link
Copy Markdown
Member

Preemptive review to help triage for the 5.0 release, @marklawlor makes the final call.

Verified against current main and it holds up. Tailwind compiles bg-black/50 to a color-mix that lightningcss resolves to NaN oklab channels, and parseColor passed them through so RN got #NaNNaNNaN80 and dropped the style. Coercing NaN to 0 matches CSS Color 4 missing component semantics, the regression test fails on main without the fix, and the diff applies cleanly. Works on v4, silently broken on v5, so I'd call it a blocker for latest.

color-mix() resolved at compile time by lightningcss can yield NaN
chromaticity channels for degenerate mixes (e.g. mixing black with
transparent in oklab). Passing NaN to colorjs.io produced an invalid
color string like "#NaNNaNNaN80" that React Native silently discards,
so utilities such as Tailwind's bg-black/50 rendered with no background.

Treat NaN channels as 0 (a missing component per CSS Color 4) for the
lab/lch/oklab/oklch cases, so the example resolves to nativewind#80.

Fixes nativewind#317
@danstepanov danstepanov force-pushed the fix-color-mix-nan-channels branch from 08dfca1 to 907e153 Compare July 8, 2026 18:45
@danstepanov danstepanov requested a review from marklawlor July 9, 2026 02:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v5 stability Tracking v5 stability for @latest release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] bg-black/50 silently fails — NaN oklab channels from lightningcss color-mix resolution

2 participants