Skip to content
Shop

CommunityJoin Our PatreonDonate

Sponsored Ads

Sponsored Ads

Problem 1

Color contrast

Approach

Do this and that like this

Solution

Solution
rb
module Util::Color
    # https://www.w3.org/WAI/WCAG21/Techniques/general/G17
    # https://webaim.org/resources/contrastchecker/
    def contrast_ratio(colour1, colour2)
      lum1 = relative_luminance(colour1)
      lum2 = relative_luminance(colour2)
      ([lum1, lum2].max + 0.05) / ([lum1, lum2].min + 0.05)
    end
  
    def relative_luminance(colour)
      colour = colour_str_to_rgb(colour) if colour.is_a? String
      transformed = {}
  
      colour.each do |key, _val|
        transformed[key] = colour[key] <= 0.04045 ? colour[key] / 12.92 : ((colour[key] + 0.055) / 1.055)**2.4
      end
      ((transformed[:red] * 0.2126) + (transformed[:green] * 0.7152) + (transformed[:blue] * 0.0722))
    end
  
    def colour_str_to_rgb(colour)
      colour = colour.downcase
      colour = colour[1..-1] if colour[0] == '#'
      {
        'red': colour[0, 2].to_i(16) / 255.0,
        'green': colour[2..3].to_i(16) / 255.0,
        'blue': colour[4..16].to_i(16) / 255.0
      }
    end
  
    def ada_compliance(colour1, colour2)
      aa = {
        'normal': false,
        'large': false,
        'graphics': false
      }
      aaa = {
        'normal': false,
        'large': false,
        'graphics': false
      }
      if contrast_ratio(colour1, colour2) >= 4.5
        aa[:normal] = true
        aaa[:large] = true
      end
      if contrast_ratio(colour1, colour2) >= 3
        aa[:large] = true
        aa[:graphics] = true
        aaa[:graphics] = true
      end
  
      aaa[:normal] = true if contrast_ratio(colour1, colour2) >= 7
  
      { "AA": aa }.merge({ "AAA": aaa })
    end
  
    def ratio_to_decimal(str_ratio)
      ratio = str_ratio.split(':')
      ratio[0] / ratio[1].to_f
    end
  
    def decimal_to_ratio(decimal)
      decimal = decimal.round(2)
      "#{decimal}:1"
    end
  end

Resources

Feedback

If you liked this problem, let us know