<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>The Dev Blog: Finding Good Color Contrast</title>
    <link>http://devblog.famundo.com/articles/2006/06/14/finding-good-color-contrast</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Putting Family Management on Rails!</description>
    <item>
      <title>Finding Good Color Contrast</title>
      <description>&lt;p&gt;Giving our Famundo users the ability to change some background colors on the header to match the logo, brough up the problem of selecting the correct color to use for text we have to write on the header. We can't default to just a specific color as it might not be readable on some of the colors. &lt;/p&gt;

&lt;p&gt;The W3C recommends how to &lt;a href="http://www.wat-c.org/tools/CCA/1.1/"&gt;select colors&lt;/a&gt; to achieve good readability. It's a nice formula to find the color contrast and brightness difference. They also recommend on a treshold to compare against, when selecting the colors. I wrote ruby code to do that calculation. You can change the tresholds to give you more latitute in selecting colors.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Return true if the difference between two colors &lt;/span&gt;
&lt;span class="comment"&gt;# matches the W3C recommendations for readability&lt;/span&gt;
&lt;span class="comment"&gt;# See http://www.wat-c.org/tools/CCA/1.1/&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;colors_diff_ok?&lt;/span&gt; &lt;span class="ident"&gt;c1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;c2&lt;/span&gt;
  &lt;span class="ident"&gt;cont&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;bright&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;find_color_diff&lt;/span&gt; &lt;span class="ident"&gt;c1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;c2&lt;/span&gt;
  &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;cont&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;500&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;bright&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;125&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;# Acceptable diff according to w3c&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="comment"&gt;# Return the contranst and brightness difference between two RGB values&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;find_color_diff&lt;/span&gt; &lt;span class="ident"&gt;c1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;c2&lt;/span&gt;
  &lt;span class="ident"&gt;r1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;g1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;b1&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;break_color&lt;/span&gt; &lt;span class="ident"&gt;c1&lt;/span&gt;
  &lt;span class="ident"&gt;r2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;g2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;b2&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;break_color&lt;/span&gt; &lt;span class="ident"&gt;c2&lt;/span&gt;
  &lt;span class="ident"&gt;cont_diff&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r1&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;r2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;abs&lt;/span&gt;&lt;span class="punct"&gt;+(&lt;/span&gt;&lt;span class="ident"&gt;g1&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;g2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;abs&lt;/span&gt;&lt;span class="punct"&gt;+(&lt;/span&gt;&lt;span class="ident"&gt;b1&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;b2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;abs&lt;/span&gt; &lt;span class="comment"&gt;# Color contrast&lt;/span&gt;
  &lt;span class="ident"&gt;bright1&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r1&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;299&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;g1&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;587&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;b1&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;114&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;1000&lt;/span&gt;
  &lt;span class="ident"&gt;bright2&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r2&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;299&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;g2&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;587&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;b2&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;114&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;1000&lt;/span&gt;
  &lt;span class="ident"&gt;brt_diff&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;bright1&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;bright2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;abs&lt;/span&gt; &lt;span class="comment"&gt;# Color brightness diff&lt;/span&gt;
  &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;cont_diff&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;brt_diff&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="comment"&gt;# Break a color into the R, G and B components    &lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;break_color&lt;/span&gt; &lt;span class="ident"&gt;rgb&lt;/span&gt;
  &lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;rgb&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt; &lt;span class="number"&gt;0xff0000&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;16&lt;/span&gt;
  &lt;span class="ident"&gt;g&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;rgb&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt; &lt;span class="number"&gt;0x00ff00&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;8&lt;/span&gt;
  &lt;span class="ident"&gt;b&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;rgb&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt; &lt;span class="number"&gt;0x0000ff&lt;/span&gt;
  &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;g&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;b&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; 
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A simple way to use it, is to have an array with different color options, and look in it for a match:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;possible_colors&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0xff0000&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0x00ff00&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0x0000ff&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0xffff00&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0x00ffff&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0xffffff&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="ident"&gt;good_color&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="comment"&gt;# We can default to black...&lt;/span&gt;
&lt;span class="ident"&gt;possible_colors&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;colors_diff_ok?&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;my_color&lt;/span&gt;
    &lt;span class="ident"&gt;good_color&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt;
    &lt;span class="keyword"&gt;break&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 14 Jun 2006 10:20:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:313f2e1de9891387f7cb9d95f8b32067</guid>
      <author>guy.naor@famundo.com (Guy Naor)</author>
      <link>http://devblog.famundo.com/articles/2006/06/14/finding-good-color-contrast</link>
      <category>Ruby</category>
      <trackback:ping>http://devblog.famundo.com/articles/trackback/18</trackback:ping>
    </item>
  </channel>
</rss>
