How do I lighten or darken a color in Ruby?
Lightening and darkening sounds like something HSL should handle well, and in theory it does. In practice, though, HSL-based adjustments often cause hue drift and saturation loss that make the resulting colors look off. You might wonder why that happens: HSL is not perceptually uniform, so the numeric adjustment does not correspond evenly to what your eye perceives. Abachrome’s lighten method operates in OKLCH space instead, where the hue and chroma stay stable across the adjustment. What we get is a lighter or darker version of the same color, not a shifted one.
Basic Usage
require 'abachrome'
base = Abachrome.from_hex('#e63946')
lighter = base.lighten(0.15) # +15% lightness
darker = base.lighten(-0.15) # -15% lightness
puts Abachrome::Outputs::CSS.format(lighter.to_srgb)
puts Abachrome::Outputs::CSS.format(darker.to_srgb)
Positive values lighten; negative values darken. The argument is a delta in OKLCH lightness units, which run from 0 to 1.
Generating Tint/Shade Scales
base = Abachrome.from_hex('#0077b6')
shades = (-4..4).map { |step| base.lighten(step * 0.08) }
shades.each_with_index do |color, i|
hex = Abachrome::Outputs::CSS.format(color.to_srgb)
puts "shade-#{i * 100}: #{hex}"
end
This produces a nine-step tint and shade scale from a single base color. The perceptual uniformity of OKLCH means the steps feel evenly spaced to the eye — which is harder to achieve reliably in HSL.
Adjusting Chroma Directly
At times you want to adjust vibrancy rather than lightness. For fine-grained control, convert to OKLCH and modify the coordinates directly before converting back:
color = Abachrome.from_hex('#06d6a0').to_oklch
coords = color.coordinates
# Boost chroma by 0.05
more_vivid = Abachrome.from_oklch(
coords[0], # keep lightness
coords[1] + 0.05, # increase chroma
coords[2] # keep hue
)
puts Abachrome::Outputs::CSS.format(more_vivid.to_srgb)
This approach gives you independent control over all three perceptual dimensions of the color. It is more verbose than lighten, but it is the right tool when you need precision.
Notes
lightenwith a positive value makes the color lighter; negative values darken it.- Passing a value that pushes lightness above 1.0 or below 0.0 may produce out-of-gamut results — use gamut mapping before CSS output if you’re adjusting by large amounts.