abachrome
Why blend colors in OKLCH instead of RGB?
Blending colors directly in sRGB produces muddy midpoints — mixing a vivid blue and a vivid yellow through sRGB often yields a grey-green that looks dull and unpredictable. OKLCH (and its sibling OKLab) are perceptually uniform: equal numeric steps correspond to equal perceived differences, so midpoints look like what your eye actually expects.
The Difference in Practice
require 'abachrome'
blue = Abachrome.from_hex('#0066ff')
yellow = Abachrome.from_hex('#ffcc00')
# Blend in sRGB (default for most libraries)
rgb_mid = blue.blend(yellow, 0.5)
puts Abachrome::Outputs::CSS.format(rgb_mid) # => muddy green-grey
# Blend in OKLCH for a perceptually uniform midpoint
blue_lch = blue.to_oklch
yellow_lch = yellow.to_oklch
lch_mid = blue_lch.blend(yellow_lch, 0.5)
puts Abachrome::Outputs::CSS.format(lch_mid) # => vibrant, balanced midpoint
Generating a Gradient Palette
require 'abachrome'
start_color = Abachrome.from_oklch(0.55, 0.22, 30) # warm orange
end_color = Abachrome.from_oklch(0.55, 0.22, 270) # cool blue
palette = Abachrome::Palette.new([start_color, end_color])
steps = palette.interpolate(steps: 7)
steps.each do |color|
puts Abachrome::Outputs::CSS.format(color.to_srgb)
end
Because lightness and chroma are held constant while hue sweeps, every stop in the gradient has the same perceived brightness — making it suitable for accessible data-visualization color scales.
When RGB Blending Is Fine
Use sRGB blending when you need pixel-perfect reproduction of a design tool’s output, or when the two colors are close together and the perceptual difference is negligible.