L-Value Contrast Ratio Grid@4x.jpg

CarMax Color System: Part 3

CarMax Color System: Part 3


Where the Research Began

As stated in the previous section, this part will show which decisions led to the final Color System 2.0.

The image below shows the exact reason we began the color system overhaul. Color System 1.0 took heavy inspiration from the 2014 Material Design color palettes but lacked the underlying logic that Material Design had. The hex value of #003366 is our “Brand Blue” which means its use is pervasive across the organization.

When the original system was created, the design team placed it in the 500 color ramp because Material Design’s guideline was to place the most used value in said ramp. What wasn’t known at the time was that the 500 color ramp was also meant to be a rough middle ground between the darkest value and the lightest value.

Luckily, between the creation of the original color system and the beginning of the overhaul, Material Design had implemented a color palette generator based on a user inputed hex value. I put our Brand Blue into the generator and it gave back the Revised version of KMX Blue. This helped us understand another flaw in Color System 1.0, the color values in each family were placed in wrong color ramps.

 
This quick exercise and my concerns over accessibility gave me enough evidence to go to our exec team & pitch an overhaul of the color system.
 

With their approval I was allowed to start digging into Color System 1.0 and begin constructing a new color system that is based on accessibility principles. Our only caveats were to keep the main three brand colors of #003366 / #FFD900 / #FFFFFF. I decided that the easiest way to keep these was to bucket them by hue. #003366 fell into 210º, #FFD900 fell into 51º, & #FFFFFF is technically part of every hue so long as Saturation is 0 and Lightness is 100.


The Color Grid Tool

For the sake of brevity, I’ll just say that there was a solid two months of me creating individual Hue-Saturation-Vibrance grids inside Illustrator and manually checking which dots passed WCAG 2.0 contrast ratio with white text. During that time I learned that across all hues, if Saturation was 0 & Vibrance was 46, it passed the 4.5:1 contrast ratio. This was the first pattern identified. Unfortunately, as soon as Saturation increases, there wasn’t an identifiable pattern of passing the contrast ratio across the entire hue range.

After two months of watching me struggle, Reid Braswell, the developer on my team took the weekend to create a microsite where I could input a hue degree and I would get a 101 x 101 dot grid of every combination of Saturation & Vibrance within that hue.

The Color Grid Tool sped up my workflow tenfold. It not only gave me more accurate color values than Illustrator, we added a WCAG filter. When turned on, the filter splits the grid into two sides. If the color passes with black text, it was rendered red. If the color passes with white text, it was left alone. Here’s a quick GIF to show this process across the whole hue range.

 
This filter gave me the next breakthrough, I identified a pattern of where that split happens across the entire hue range.
 
 
 

Uncovering WCAG Contrast Ratio

With that pattern in mind, I had to figure out what was the common denominator? I took samples from several hues so I had a range of data to work with. Here’s what we saw:

After that exercise I finally understood the relationship between WCAG & the Lightness value (L*-value) from the CIE-Lab color mode.


 
Text color with L*-values 0-49.9 are compliant on a white background. Text color with L*-values 50.1-100 are compliant on a black background.
 

How Understanding L*-Value Shaped Our System

Knowing about black & white text was a good start but I wanted to know, “what about everything in-between?” I took some time and created another graph. This one mapped out foreground vs background L*-value and noted which ones passed WCAG AA at 14pt (green) & 18pt (yellow). If nothing else came out of our rework, this one graph would be enough to share with other designers & companies to help them create more accessible color systems themselves.


Taking a Step Back

At this point I was certain that the L*-value graph will be pivotal for the new system. I knew the effect it had on passing WCAG but didn’t how how to use it. This is when I took a look back at the old color system and did the contrast grid exercise seen in Part 2. The scattered contrast grid had to relate to L*-value so I did one more exercise with the old system. I laid out the L*-values of every color value and came out with the graph below. The differences in lines helped me understand why the contrast grid was so inconsistent. Each color family had a different curve so none of them were consistent in defining the color ramps (e.g. Yellow-900 had an L*-value of 74 while KMX Blue-900 had a value of 6).

 
 

Applying What Was Learned

After 3 months, I had a solid foundation of research to begin creating the new color system. I started by figuring out how many values we wanted per family. Originally the team was okay with 10 but our lightest values weren’t subtle enough so we decided to add the 50 value color ramp. Next was deciding what each ramp’s L*-value should be. The team agreed that we needed a decent range of light to dark and the research around the contrast graph I knew we had options. If I did it right, I could have a symmetrical color contrast grid. When combined, all of the dark values would be compliant with all of the light values.

With the old system’s variances lines spelled out, I tried a couple of different systematic approaches. The darkest value could start around 15 since any lower and every hue looked too close to black. The lightest value could be as high as 98 since that is when the values were distinguishable from white.

 
 

I opted for a non-linear approach; the more unique each aspect of the system, the more own-able it could be. We ended up with the ones above for the color families. More on the yellow line later.


Funneling Research into the Color Grid Tool

Now that I had the L*-values, it became a question of how do we isolate these within each hue? Luckily my developer had a solution; he converted each HSV value into CIE-LAB in the code. If the dot on the grid didn’t have the value we were looking for, it wasn’t rendered. Below is the 210º grid with only the correct values being shown.


The Problem with Yellow

Before I wrap this all up, let’s address the yellow color family. After multiple iterations of forming the L*-value color ramps we quickly realized that yellow would be an issue. Any value less than 91 in the 60º hue range became an olive color which looked awful. I explained the problem to the team and we decided to give up on trying to shoehorn in our systematic approach to a lost cause. For the final KMX Yellow family we took the old system’s values and only slightly tweaked them.


The Final Step

Now that all of the research is done, the last phase of the rework was the easiest to do. The first hue we had in place was 210º (CarMax’s Brand Blue). From there I made jumps of 15º and took a quick look at how the values in those hues looked. I wanted to make sure we had all the color families from the old system accounted for and added in the Raspberry family.

 

The Blue Family: Hue 210º

In another push for an own-able system, I had each hue have a unique curve that would determine which values would be selected for the final system. Blue had a great selection of values so the curve was kept fairly round.

 

The Slate Family: Hue 210º

The Slate family is actually my favorite one. It was created using the same 210º hue but instead of the curve going clockwise, I had it go counter clockwise so it hit the more muted values first. This gave us a “gray” family but towards the darker values there was a hint of blue which added some needed personality.

 

The Green Family: Hue 105º

Green was surprisingly hard to nail down. Side note: because of evolution, humans are able to see more shades of green when compared to other hues. Because of that trait it was difficult to find a curve that created a cohesive color family but also cohesive with the other families. I ended up using a vertical oval for it to keep the saturation high in the darker values.

 

The Raspberry Family: Hue 330º

The Raspberry and Red families were only 30º apart so their curves are relatively similar. Their ovals are angled to make sure I could hit the high saturation and vibrance range but get into the deep values for the 1000 color ramp.

 

The Red Family: Hue 360º


CarMax Color System 2.0

With all the values established, the color system was complete. Our goal of creating a systematic and accessibility-first color system was accomplished.