Color Crate API Reference
Overview
The color crate provides color representation, conversion, parsing, and manipulation for Rust. It implements CSS Color Level 4 with 16 color spaces, static and dynamic color types, and gradient generation.
When to Use
- •Representing colors in any of 16 color spaces (sRGB, Oklab, Display P3, etc.)
- •Parsing CSS color strings (
#hex,rgb(),oklch(), named colors) - •Converting between color spaces
- •Interpolating colors for gradients or animations
- •Perceptual color manipulation (lightness, chroma, hue)
Not for: CMYK/print colors, ICC profiles, spectral colors, >3 component spaces
Color Types
Static Types (compile-time color space)
rust
use color::{OpaqueColor, AlphaColor, PremulColor, Srgb, Oklab};
// OpaqueColor - no alpha
let red: OpaqueColor<Srgb> = OpaqueColor::new([1.0, 0.0, 0.0]);
// AlphaColor - straight alpha
let semi: AlphaColor<Srgb> = AlphaColor::new([1.0, 0.0, 0.0, 0.5]);
let from_u8 = AlphaColor::<Srgb>::from_rgba8(255, 0, 0, 128);
// PremulColor - premultiplied alpha (efficient for compositing)
let premul: PremulColor<Srgb> = semi.premultiply();
Dynamic Type (runtime color space)
rust
use color::{DynamicColor, ColorSpaceTag, parse_color};
let color = parse_color("oklch(0.7 0.15 240)")?;
let converted = color.convert(ColorSpaceTag::Srgb);
Color Spaces
16 spaces available as types and ColorSpaceTag variants:
| Space | Type | Layout | Notes |
|---|---|---|---|
Srgb | RGB | Rectangular | Standard web RGB |
LinearSrgb | RGB | Rectangular | Linear-light sRGB |
DisplayP3 | RGB | Rectangular | Wide gamut display |
A98Rgb | RGB | Rectangular | Adobe RGB 1998 |
ProphotoRgb | RGB | Rectangular | D50 white point |
Rec2020 | RGB | Rectangular | HDR/wide gamut |
XyzD50 | XYZ | Rectangular | CIE XYZ, D50 |
XyzD65 | XYZ | Rectangular | CIE XYZ, D65 |
Lab | Lab | Rectangular | CIE Lab |
Oklab | Lab | Rectangular | Perceptually uniform |
Hsl | Cylindrical | HueFirst | Hue, Saturation, Lightness |
Hwb | Cylindrical | HueFirst | Hue, Whiteness, Blackness |
Lch | Cylindrical | HueThird | Lightness, Chroma, Hue |
Oklch | Cylindrical | HueThird | Oklab cylindrical form |
Aces2065_1 | RGB | Rectangular | ACES white point |
AcesCg | RGB | Rectangular | ACES white point |
Conversion
rust
// Static conversion let srgb: OpaqueColor<Srgb> = OpaqueColor::new([1.0, 0.0, 0.0]); let oklab: OpaqueColor<Oklab> = srgb.convert::<Oklab>(); let lab: OpaqueColor<Lab> = oklab.convert::<Lab>(); // Dynamic conversion let dyn_color = DynamicColor::from_alpha_color(srgb.with_alpha(1.0)); let converted = dyn_color.convert(ColorSpaceTag::Oklch); // Back to static let alpha: AlphaColor<Srgb> = converted.to_alpha_color::<Srgb>();
Parsing CSS Colors
rust
use color::{parse_color, DynamicColor, ParseError};
// All CSS Color 4 formats supported
let c1 = parse_color("red")?; // Named (142 X11 colors)
let c2 = parse_color("#ff0000")?; // Hex
let c3 = parse_color("rgb(255 0 0)")?; // RGB
let c4 = parse_color("hsl(0 100% 50%)")?; // HSL
let c5 = parse_color("oklch(0.7 0.15 30)")?; // Oklch
let c6 = parse_color("color(display-p3 1 0 0)")?; // color() function
let c7 = parse_color("rgb(255 0 0 / 50%)")?; // With alpha
// Missing components (CSS Color 4)
let c8 = parse_color("hsl(none 100% 50%)")?;
Serialization
DynamicColor implements Display for CSS output:
rust
let color = parse_color("oklch(0.7 0.15 240)")?;
println!("{}", color); // oklch(0.7 0.15 240)
Interpolation
rust
use color::{HueDirection, ColorSpaceTag};
// Static interpolation
let c1: OpaqueColor<Srgb> = OpaqueColor::new([1.0, 0.0, 0.0]);
let c2: OpaqueColor<Srgb> = OpaqueColor::new([0.0, 0.0, 1.0]);
let mid = c1.lerp(c2, 0.5, HueDirection::Shorter);
// Dynamic interpolation
let interp = color1.interpolate(color2, ColorSpaceTag::Oklch, HueDirection::default());
let at_half = interp.eval(0.5);
HueDirection: Shorter (default), Longer, Increasing, Decreasing
Gradients
Generate piecewise-linear gradient stops for rendering:
rust
use color::{gradient, DynamicColor, ColorSpaceTag, HueDirection, Srgb};
let stops = gradient::<Srgb>(
start_color,
end_color,
ColorSpaceTag::Oklab, // Interpolation space
HueDirection::Shorter,
0.01, // Tolerance (deltaEOK)
);
for (t, color) in stops {
// t in [0.0, 1.0], color is PremulColor<Srgb>
}
// For HTML canvas compatibility (unpremultiplied interpolation):
let stops = gradient_unpremultiplied::<Srgb>(start, end, interp_cs, direction, tolerance);
Color Manipulation
rust
// Lightness/chroma/hue manipulation let darker = color.map_lightness(|l| l * 0.8); let muted = color.scale_chroma(0.5); let complement = color.map_hue(|h| (h + 180.0) % 360.0); // Alpha manipulation let with_alpha = opaque.with_alpha(0.5); let (opaque, alpha) = alpha_color.split(); let scaled = alpha_color.multiply_alpha(0.5); // Perceptual metrics let lum = color.relative_luminance(); // WCAG 2.1 let dist = color1.difference(color2); // Euclidean in current space
Packed Integer Types
rust
use color::{Rgba8, PremulRgba8};
// 8-bit sRGB
let rgba8: Rgba8 = alpha_color.to_rgba8();
let packed: u32 = rgba8.to_u32();
let arr: [u8; 4] = rgba8.to_u8_array();
// Premultiplied 8-bit
let premul8: PremulRgba8 = premul_color.to_rgba8();
Named Color Palette
rust
use color::palette::css::{RED, ALICE_BLUE, TRANSPARENT};
let red: AlphaColor<Srgb> = RED;
142 X11/CSS named colors available as constants.
Quick Reference
| Operation | Code |
|---|---|
| Create from components | OpaqueColor::<Srgb>::new([r, g, b]) |
| Create from u8 | AlphaColor::<Srgb>::from_rgba8(r, g, b, a) |
| Parse CSS | parse_color("oklch(0.7 0.15 240)")? |
| Convert space | color.convert::<TargetSpace>() |
| Add alpha | opaque.with_alpha(0.5) |
| Premultiply | alpha.premultiply() |
| Interpolate | c1.lerp(c2, t, HueDirection::Shorter) |
| To 8-bit | color.to_rgba8() |
| Scale saturation | color.scale_chroma(0.5) |
| Adjust lightness | color.map_lightness(|l| l * 0.8) |
| WCAG luminance | color.relative_luminance() |
Common Mistakes
| Mistake | Fix |
|---|---|
| Interpolating in sRGB | Use Oklab/Oklch for perceptually uniform gradients |
| Forgetting premultiply for compositing | Use PremulColor or call .premultiply() before blending |
Using AlphaColor components directly after convert | Alpha is separate; access via .split() or component methods |
| Expecting hue interpolation to go "the right way" | Specify HueDirection::Shorter or explicit direction |
Cargo Features
- •std (default) - Standard library float ops
- •libm - For no_std environments
- •bytemuck - Pod/Zeroable traits
- •serde - Serialization support