-
-
Notifications
You must be signed in to change notification settings - Fork 36.3k
Description
Description
Summary
Color.setStyle() fails to parse several valid CSS color formats and can silently leave the previous color unchanged without warning.
Affected area
Environment
- OS: Windows
- Branch/Repo: three.js local workspace
- Date: 2026-03-17
Verified bugs
- Silent no-op when
rgb/rgba/hsl/hslamodel matches but component regex does not. - CSS Color 4 space/slash syntax is not parsed:
rgb(255 0 0)rgb(255 0 0 / 0.5)hsl(120deg 100% 50%)
- Percentage alpha is rejected in rgba-like forms:
rgb(100%,50%,10%,50%)
- Color model names are case-sensitive:
RGB(255,0,0)HSL(120,100%,50%)
Reproduction
Run in repo root:
node -e "import { Color } from './src/math/Color.js'; const samples=['rgb(255 0 0)','rgb(255 0 0 / 0.5)','hsl(120deg 100% 50%)','rgb(100%,50%,10%,50%)','RGB(255,0,0)','HSL(120,100%,50%)']; for (const s of samples){ const c=new Color(0x123456); c.setStyle(s); console.log(s,'=>',c.getHexString()); }"Observed output pattern:
- Most samples keep previous value (
123456) instead of setting a new color. - Uppercase model names emit unknown model warnings and do not parse.
Expected behavior
- Parse valid CSS color forms (including modern CSS Color 4 forms), or
- If a format is intentionally unsupported, emit a clear warning and do not fail silently.
Actual behavior
- Several valid forms are not parsed.
- In multiple failure paths, method returns
thiswithout warning, leaving stale color values.
Why this matters
- Causes hard-to-debug color bugs when user input comes from CSS values.
- Silent no-op behavior can mask data issues and produce incorrect rendering.
Existing test coverage gap
- Current unit tests mostly cover comma-separated lowercase legacy forms in test/unit/src/math/Color.tests.js.
- No coverage for CSS Color 4 space/slash syntax, uppercase model names, or alpha percentages.
Reproduction steps
1.node -e "import { Color } from './src/math/Color.js'; const samples=['rgb(255 0 0)','rgb(255 0 0 / 0.5)','hsl(120deg 100% 50%)','rgb(100%,50%,10%,50%)','RGB(255,0,0)','HSL(120,100%,50%)']; for (const s of samples){ const c=new Color(0x123456); c.setStyle(s); console.log(s,'=>',c.getHexString()); }" run it
2.Most samples keep previous value (123456) instead of setting a new color.
3.Uppercase model names emit unknown model warnings and do not parse.
Code
node -e "import { Color } from './src/math/Color.js'; const samples=['rgb(255 0 0)','rgb(255 0 0 / 0.5)','hsl(120deg 100% 50%)','rgb(100%,50%,10%,50%)','RGB(255,0,0)','HSL(120,100%,50%)']; for (const s of samples){ const c=new Color(0x123456); c.setStyle(s); console.log(s,'=>',c.getHexString()); }"
Live example
- jsfiddle-latest-release WebGLRenderer
- jsfiddle-dev WebGLRenderer
- jsfiddle-latest-release WebGPURenderer
- jsfiddle-dev WebGPURenderer
Screenshots
No response
Version
r183.1
Device
Desktop
Browser
Chrome
OS
Windows