M8: color-mix(): a none in color() is a missing component too

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Trevor BrownandClaude Fable 5.1 committed 2026-11-01 11:54:35 -05:00
1 parent 8b6c92796e
commit d72f096186
2 files changed
+13 -1

No files matched your search

+4 -1
View File
@@ -218,12 +218,15 @@ fn color_fn(args: &str, profile: ColorProfile) -> Eval {
None => 1.0,
};
let c = Color::new(value(r)?, value(g)?, value(b)?, a);
// A `none` is 0 here and missing in a mix: reds, greens and blues are analogous across the RGB
// spaces (CSS Color 4 section 12.2), so a missing channel stays missing through the conversion.
let missing = Missing { r: *r == "none", g: *g == "none", b: *b == "none", a: alpha == Some("none") };
let (from, why) = match *space {
"srgb" => (ColorProfile::Srgb, None),
"display-p3" => (ColorProfile::DisplayP3, None),
_ => (ColorProfile::Srgb, Some("only the srgb and display-p3 spaces are read: its values were taken as sRGB")),
};
Ok((from.conversion_to(profile).apply(c), why, Missing::NONE))
Ok((from.conversion_to(profile).apply(c), why, missing))
}
/// A CSS number, a percentage (100% is 1) or `none` (0); finite only.
+9
View File
@@ -86,6 +86,15 @@ fn color_mix_in_srgb_oklab_and_oklch() {
assert_eq!(rgba8(fill("color-mix(in oklab, rgb(none 0 0), red)").0), rgba8(fill("color-mix(in oklab, black, red)").0));
// Missing in both stays missing through a nested mix and is carried in the outer one.
assert_eq!(rgba8(fill("color-mix(in srgb, color-mix(in srgb, rgb(0 255 0 / none), rgb(0 255 0 / none)), red)").0), Some([128, 128, 0, 255]));
// `color()` gives its `none` values the same way, in either of its spaces (reds, greens and
// blues are analogous across RGB spaces, CSS Color 4 section 12.2).
assert_eq!(rgba8(fill("color-mix(in srgb, color(srgb 1 0 0 / none), blue)").0), Some([128, 0, 128, 255]));
assert_eq!(rgba8(fill("color-mix(in srgb, color(srgb none 0 0), red)").0), Some([255, 0, 0, 255]));
assert_eq!(rgba8(fill("color-mix(in srgb, color(display-p3 none 0 0), red)").0), Some([255, 0, 0, 255]));
assert_eq!(
rgba8(fill("color-mix(in srgb, color-mix(in srgb, color(srgb 0 1 0 / none), color(srgb 0 1 0 / none)), red)").0),
Some([128, 128, 0, 255])
);
// Nested, with color() inside.
assert_eq!(rgba8(fill("color-mix(in srgb, color-mix(in srgb, red, blue), color(srgb 0 1 0) 0%)").0), Some([128, 0, 128, 255]));
}