From eb73f021c626166b54d4b24263f269a4fc91c680 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Mon, 26 Oct 2026 05:37:27 +0100 Subject: [PATCH] Keep 8-bit alpha when printing colours with Color::to_css Found while testing crates/color/src/lib.rs:198 (Color::to_css) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/color/src/lib.rs | 9 ++++++++- crates/color/src/tests.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/color/src/lib.rs b/crates/color/src/lib.rs index 7ce1df5e..0b7ae704 100644 --- a/crates/color/src/lib.rs +++ b/crates/color/src/lib.rs @@ -195,7 +195,14 @@ impl Color { /// CSS `rgba(...)` / hex text for copy-as-CSS. pub fn to_css(self) -> String { let [r, g, b, _] = self.to_rgba8(); - if self.a >= 0.999 { self.to_css_hex() } else { format!("rgba({r}, {g}, {b}, {:.2})", self.a) } + if self.a >= 0.999 { + return self.to_css_hex(); + } + // Two decimals when they keep the 8-bit alpha, three otherwise (near-transparent colours). + let a8 = |a: f32| (a.clamp(0.0, 1.0) * 255.0).round() as u8; + let short = format!("{:.2}", self.a); + let alpha = if short.parse::().is_ok_and(|v| a8(v) == a8(self.a)) { short } else { format!("{:.3}", self.a) }; + format!("rgba({r}, {g}, {b}, {alpha})") } /// Linear interpolation in sRGB (as gradients render). diff --git a/crates/color/src/tests.rs b/crates/color/src/tests.rs index 6fedad83..2b628b71 100644 --- a/crates/color/src/tests.rs +++ b/crates/color/src/tests.rs @@ -133,3 +133,11 @@ fn malformed_alpha_or_extra_args_rejected() { assert_eq!(Color::parse_css("rgb(1,2,3)").unwrap().a, 1.0); assert_eq!(Color::parse_css("rgba(1,2,3,0.5)").unwrap().a, 0.5); } + +#[test] +fn to_css_round_trips_every_alpha() { + for a in 0..=255u8 { + let c = Color::from_rgba8(10, 20, 30, a); + assert_eq!(Color::parse_css(&c.to_css()).unwrap().to_rgba8(), c.to_rgba8(), "alpha {a}: {}", c.to_css()); + } +}