Lighten or darken a hexadecimal color in Ruby on Rails

If you have a hexadecimal color (string) that you want to lighten or darken, these two methods will be very handy for you.

These both take a hexadecimal color as a string, and also an amount to lighten or darken.

# Amount should be a decimal between 0 and 1. Lower means darker
def darken_color(hex_color, amount=0.4)
  hex_color = hex_color.gsub('#','')
  rgb = hex_color.scan(/../).map {|color| color.hex}
  rgb[0] = (rgb[0].to_i * amount).round
  rgb[1] = (rgb[1].to_i * amount).round
  rgb[2] = (rgb[2].to_i * amount).round
  "#%02x%02x%02x" % rgb
end
  
# Amount should be a decimal between 0 and 1. Higher means lighter
def lighten_color(hex_color, amount=0.6)
  hex_color = hex_color.gsub('#','')
  rgb = hex_color.scan(/../).map {|color| color.hex}
  rgb[0] = [(rgb[0].to_i + 255 * amount).round, 255].min
  rgb[1] = [(rgb[1].to_i + 255 * amount).round, 255].min
  rgb[2] = [(rgb[2].to_i + 255 * amount).round, 255].min
  "#%02x%02x%02x" % rgb
end

Examples to use these would be:

darken_color("#ff0000", 0.4)
lighten_color("#ff0000", 0.7)

If you have a color that you want to lighten or darken depending on the color (you basically want to get a good contrast), you can use these methods:

def contrasting_text_color(hex_color)
  color = hex_color.gsub('#','')
  convert_to_brightness_value(color) > 382.5 ? darken_color(color) : lighten_color(color)
end

def convert_to_brightness_value(hex_color)
   (hex_color.scan(/../).map {|color| color.hex}).sum
end

Credit for these last two methods goes to Charlie Park, I got them from his blog post.

By Joel Friedlaender