Color Space Conversions
Relevant source files
The following files were used as context for generating this wiki page:
- packages/color-contrast/src/index.ts
- packages/color-contrast/src/types.ts
- packages/color-contrast/src/convert/hsl-to-srgb.test.ts
- packages/color-contrast/src/convert/hwb-to-srgb.test.ts
- packages/color-contrast/src/convert/lab-to-xyz.test.ts
- packages/color-contrast/src/gamut-map.test.ts
- packages/color-contrast/src/parse/index.test.ts
The color space conversion system within the @siluat/color-contrast library provides a robust pipeline for transforming various CSS color formats into a unified sRGB representation. This conversion is essential for calculating WCAG 2.1 contrast ratios, which require colors to be resolved to opaque sRGB values before luminance evaluation.
The system supports a wide range of color spaces, including traditional models like HSL and HWB, as well as modern, perceptually uniform spaces like LAB, LCH, OKLAB, and OKLCH. It implements the CSS Color Level 4 specifications for gamut mapping and wide-gamut transformations to ensure that colors rendered in the browser match the library's internal calculations.
Sources: packages/color-contrast/README.md, packages/color-contrast/src/index.ts:38-60
Conversion Architecture
The core of the conversion logic resides in a centralized pipeline that routes ParsedColor objects through specific transformation functions based on their color space. The final destination for all paths is the SRGBColor format.
The diagram illustrates the transformation paths from various input color spaces to the final sRGB output used for contrast calculation.
Sources: packages/color-contrast/src/index.ts:38-60
Supported Color Spaces
The library handles multiple data structures representing different color models. All models include an alpha channel to support transparency.
| Space | Components | Description |
|---|---|---|
| sRGB | r, g, b | Standard RGB (0-1 range). |
| HSL | h, s, l | Hue, Saturation, Lightness. |
| HWB | h, w, b | Hue, Whiteness, Blackness. |
| LAB | l, a, b | CIE LAB (perceptually uniform). |
| LCH | l, c, h | Cylindrical representation of LAB. |
| OKLAB | l, a, b | Optimized perceptual color space. |
| OKLCH | l, c, h | Cylindrical representation of OKLAB. |
Sources: packages/color-contrast/src/types.ts:4-65
Key Transformation Modules
Linear and Perceptual Conversions
For wide-gamut colors (LAB, LCH, OKLAB), the system utilizes a multi-step pipeline involving XYZ-D65 as an intermediate connection point.
- LAB to XYZ: Converts CIE LAB coordinates to XYZ-D65 using a piecewise function that handles both linear and cubic segments.
- XYZ to OKLAB: Maps the physical XYZ space to the perceptually uniform OKLAB space.
- LCH to LAB: Converts cylindrical coordinates (Chroma, Hue) to Cartesian coordinates (a, b).
Sources: packages/color-contrast/src/index.ts:38-60, packages/color-contrast/src/convert/lab-to-xyz.test.ts
HSL and HWB to sRGB
Standard web color models are converted directly to sRGB. The HWB conversion includes a "short-circuit" path for normalization: if whiteness and blackness sum to more than 100%, the color is treated as an achromatic gray.
Sources: packages/color-contrast/src/convert/hsl-to-srgb.test.ts, packages/color-contrast/src/convert/hwb-to-srgb.test.ts:74-106
Gamut Mapping
When wide-gamut colors (like OKLCH) fall outside the standard sRGB gamut, the library applies the CSS Color Level 4 gamut mapping algorithm. This process preserves the intended hue and lightness while performing a chroma binary search in the OKLCH space to find the closest representable sRGB color.
- Lightness Extremes: Colors with $L \ge 1$ are mapped to white; $L \le 0$ are mapped to black.
- In-Gamut Preservation: Colors already within the sRGB range are passed through with minimal adjustment.
Sources: packages/color-contrast/src/gamut-map.test.ts, packages/color-contrast/src/index.ts:50-51
Internal Data Flow Example
The following sequence shows how a lab() color string is processed into a usable luminance value for contrast checks.
Sequence of internal function calls for LAB color conversion.
Sources: packages/color-contrast/src/index.ts:41-60, packages/color-contrast/src/parse/index.test.ts:98-106
Implementation Details
The library ensures high precision during conversion, as evidenced by test suites validating results against reference implementations like Color.js.
// Example of the centralized conversion router
function toSrgb(parsed: ParsedColor): SRGBColor {
switch (parsed.space) {
case 'srgb':
return parsed;
case 'hsl':
return hslToSrgb(parsed);
case 'hwb':
return hwbToSrgb(parsed);
case 'oklch':
return gamutMapOklch(parsed);
// ... complex wide-gamut pipelines
}
}
Sources: packages/color-contrast/src/index.ts:38-60
Conclusion
The color space conversion system is a critical infrastructure component of the @siluat/color-contrast project. By implementing standard-compliant transformations and gamut mapping, it allows the library to provide accurate accessibility metrics for modern web designs that utilize advanced color models beyond simple hex codes.