DEV Community

Discussion on: CSS Variables and Redis: How color customization is implemented on Forem

Collapse
 
link2twenty profile image
Andrew Bone

Very cool Ben. I feel good that contrast thing sort of matches the one I threw together a couple of years ago 😅

Comment for #735

I've not ever written ruby before so feel free to write something yourself but something like this is what I was thinking

def contrast_verified_hex(fg, bg)
  # WCAG20: https://www.w3.org/TR/WCAG20/#visual-audio-contrast
  f = fg[1..-1].chars.each_slice(2).map(&:join).map {|h| h.hex / 255.0}
  b = bg[1..-1].chars.each_slice(2).map(&:join).map {|h| h.hex / 255.0}
  
  # Formula: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
  def RL(d) d <= 0.03928 ? d / 12.92 : ((d + 0.055) / 1.055) ** 2.4 end
  
  # Formula: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
  fg_lum = 0.2126 * RL(f[0]) + 0.7152 * RL(f[1]) + 0.0722 * RL(f[2]) + 0.05
  bg_lum = 0.2126 * RL(b[0]) + 0.7152 * RL(b[1]) + 0.0722 * RL(b[2]) + 0.05
  
  # Formula: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
  ratio = fg_lum < bg_lum ? bg_lum / fg_lum : fg_lum / bg_lum

  # The visual presentation of text and images of text has a contrast ratio of at least 7:1 (WCAG20)
  case  
  when ratio >= 7
    return fg
  when bg_lum < 0.5
    return "#FFFFFF"
  else  
    return "#000000"
  end
end

Then in user_decorator.rb you could say something like

def enriched_colors
    if bg_color_hex.blank?
      {
        bg: assigned_color[:bg],
        text: assigned_color[:text]
      }
    else
      {
        bg: bg_color_hex || assigned_color[:bg],
        text: contrast_verified_hex(text_color_hex, bg_color_hex) || assigned_color[:text]
      }
    end
  end