a-handy-sass-powered-tool-for-making-balanced-color-palettes

For those who may not come from a design background, selecting a color palette is often based on personal preferences. Choosing colors might be done with an online color tool, sampling from an image, “borrowing” from favorite brands, or just sort of randomly picking from a color wheel until a palette “just feels right.”

Our goal is to better understand what makes a palette “feel right” by exploring key color attributes with Sass color functions. By the end, you will become more familiar with:

  • The value of graphing a palette’s luminance, lightness, and saturation to assist in building balanced palettes
  • The importance of building accessible contrast checking into your tools
  • Advanced Sass functions to extend for your own explorations, including a CodePen you can manipulate and fork

What you’ll ultimately find, however, is that color on the web is a battle of hardware versus human perception.

What makes color graphing useful

You may be familiar with ways of declaring colors in stylesheets, such as RGB and RGBA values, HSL and HSLA values, and HEX codes.

rbg(102,51,153)
rbga(102,51,153, 0.6)
hsl(270, 50%, 40%)
hsla(270, 50%, 40%, 0.6)
#663399

Those values give devices instructions on how to render color. Deeper attributes of a color can be exposed programmatically and leveraged to understand how a color relates to a broader palette.

The value of graphing color attributes is that we get a more complete picture of the relationship between colors. This reveals why a collection of colors may or may not feel right together. Graphing multiple color attributes helps hint at what adjustments can be made to create a more harmonious palette. We’ll look into examples of how to determine what to change in a later section.

Two useful measurements we can readily obtain using built-in Sass color functions are lightness and saturation.

  • Lightness refers to the mix of white or black with the color.
  • Saturation refers to the intensity of a color, with 100% saturation resulting in the purest color (no grey present).
$color: rebeccapurple;

@debug lightness($color);
// 40%

@debug saturation($color);
// 50%;

However, luminance may arguably be the most useful color attribute. Luminance, as represented in our tool, is calculated using the WCAG formula which assumes an sRGB color space. Luminance is used in the contrast calculations, and as a grander concept, also aims to get closer to quantifying the human perception of relative brightness to assess color relationships. This means that a tighter luminance value range among a palette is likely to be perceived as more balanced to the human eye. But machines are fallible, and there are exceptions to this rule that you may encounter as you manipulate palette values. For more extensive information on luminance, and a unique color space called CIELAB that aims to even more accurately represent the human perception of color uniformity, see the links at the end of this article.

Additionally, color contrast is exceptionally important for accessibility, particularly in terms of legibility and distinguishing UI elements, which can be calculated programmatically. That’s important in that it means tooling can test for passing values. It also means algorithms can, for example, return an appropriate text color when passed in the background color. So our tool will incorporate contrast checking as an additional way to gauge how to adjust your palette.

The functions demonstrated in this project can be extracted for helping plan a contrast-safe design system palette, or baked into a Sass framework that allows defining a custom theme.

Sass as a palette building tool

Sass provides several traditional programming features that make it perfect for our needs, such as creating and iterating through arrays and manipulating values with custom functions. When coupled with an online IDE, like CodePen, that has real-time processing, we can essentially create a web app to solve specific problems such as building a color palette.

Here is a preview of the tool we’re going to be using:

See the Pen


Sass Color Palette Grapher
by Stephanie Eckles (@5t3ph)


on CodePen.

Features of the Sass palette builder

  • It outputs an aspect ratio-controlled responsive graph for accurate plot point placement and value comparing.
  • It leverages the result of Sass color functions and math calculations to correctly plot points on a 0–100% scale.
  • It generates a gradient to provide a more traditional “swatch” view.
  • It uses built-in Sass functions to extract saturation and lightness values.
  • It creates luminance and contrast functions (forked from Material Web Components in addition to linking in required precomputed linear color channel values).
  • It returns appropriate text color for a given background, with a settings variable to change the ratio used.
  • It provides functions to uniformly scale saturation and lightness across a given palette.

Using the palette builder

To begin, you may wish to swap from among the provided example palettes to get a feel for how the graph values change for different types of color ranges. Simply copy a palette variable name and swap it for $default as the value of the $palette variable which can be found under the comment SWAP THE PALETTE VARIABLE.

Next, try switching the $contrastThreshold variable value between the predefined ratios, especially if you are less familiar with ensuring contrast passes WCAG guidelines.

Then try to adjust the $palette-scale-lightness or $palette-scale-saturation values. Those feed into the palette function and uniformly scale those measurements across the palette (up to the individual color’s limit).

Finally, have a go at adding your own palette, or swap out some colors within the examples. The tool is a great way to explore Sass color functions to adjust particular attributes of a color, some of which are demonstrated in the $default palette.

Interpreting the graphs and creating balanced, accessible palettes

The graphing tool defaults to displaying luminance due to it being the most reliable indicator of a balanced palette, as we discussed earlier. Depending on your needs, saturation and lightness can be useful metrics on their own, but mostly they are signalers that can help point to what needs adjusting to bring a palette’s luminance more in alignment. An exception may be creating a lightness scale based on each value in your established palette. You can swap to the $stripeBlue example for that.

The $default palette is actually in need of adjustment to get closer to balanced luminance:

The $default palette’s luminance graph

A palette that shows well-balanced luminance is the sample from Stripe ($stripe):

The $stripe palette luminance graph

Here’s where the tool invites a mind shift. Instead of manipulating a color wheel, it leverages Sass functions to programmatically adjust color attributes.

Check the saturation graph to see if you have room to play with the intensity of the color. My recommended adjustment is to wrap your color value with the scale-color function and pass an adjusted $saturation value, e.g. example: scale-color(#41b880, $saturation: 60%). The advantage of scale-color is that it fluidly adjusts the value based on the given percent.

Lightness can help explain why two colors feel different by assigning a value to their brightness measured against mixing them with white or black. In the $default palette, the change-color function is used for purple to align it’s relative $lightness value with the computed lightness() of the value used for the red.

The scale-color function also allows bundling both an adjusted $saturation and $lightness value, which is often the most useful. Note that provided percents can be negative.

By making use of Sass functions and checking the saturation and lightness graphs, the $defaultBalancedLuminance achieves balanced luminance. This palette also uses the map-get function to copy values from the $default palette and apply further adjustments instead of overwriting them, which is handy for testing multiple variations such as perhaps a hue shift across a palette.

The $defaultBalancedLuminance luminance graph

Take a minute to explore other available color functions.

http://jackiebalzer.com/color offers an excellent web app to review effects of Sass and Compass color functions.

Contrast comes into play when considering how the palette colors will actually be used in a UI. The tool defaults to the AA contrast most appropriate for all text: 4.5. If you are building for a light UI, then consider that any color used on text should achieve appropriate contrast with white when adjusting against luminance, indicated by the center color of the plot point.

Tip: The graph is set up with a transparent background, so you can add a background rule on body if you are developing for a darker UI.

Further reading

Color is an expansive topic and this article only hits the aspects related to Sass functions. But to truly understand how to create harmonious color systems, I recommend the following resources:

  • Color Spaces – is a super impressive deep-dive with interactive models of various color spaces and how they are computed.
  • Understanding Colors and Luminance – A beginner-friendly overview from MDN on color and luminance and their relationship to accessibility.
  • Perpetually Uniform Color Spaces – More information on perceptually uniform color systems, with an intro the tool HSLuv that converts values from the more familiar HSL color space to the luminance-tuned CIELUV color space.
  • Accessible Color Systems – A case study from Stripe about their experience building an accessible color system by creating custom tooling (which inspired this exploration and article).
  • A Nerd’s Guide to Color on the Web – This is a fantastic exploration of the mechanics of color on the web, available right here on CSS-Tricks.
  • Tanaguru Contrast Finder – An incredible tool to help if you are struggling to adjust colors to achieve accessible contrast.
  • ColorBox – A web app from Lyft that further explores color scales through graphing.
  • Designing Systematic Colors – Describes Mineral UI‘s exceptional effort to create color ramps to support consistent theming via a luminance-honed palette.
  • How we designed the new color palettes in Tableau 10 – Tableau exposed features of their custom tool that helped them create a refreshed palette based on CIELAB, including an approachable overview of that color space.

51 comments

  1. Hi there! This is my first comment here so I just wanted to give a quick shout out and say I really enjoy reading through your articles.

    Can you suggest any other blogs/websites/forums that cover the same subjects?
    Many thanks!

  2. My brother recommended I would possibly like this blog.
    He used to be entirely right. This post actually made my day.
    You can not believe simply how a lot time I had spent for this information! Thank you!

  3. When someone writes an piece of writing he/she retains the plan of a
    user in his/her mind that how a user can know it.

    Thus that’s why this article is outstdanding. Thanks!

  4. Hello, i read your blog from time to time and i own a similar one and i was just
    wondering if you get a lot of spam responses?
    If so how do you protect against it, any plugin or anything
    you can recommend? I get so much lately it’s driving me crazy
    so any assistance is very much appreciated.

  5. Heya i am for the first time here. I came across this board and
    I find It really useful & it helped me out much. I hope to give something back and
    help others like you helped me.

  6. Hi, I do believe this is a great web site. I stumbledupon it 😉 I’m going to revisit once again since I
    bookmarked it. Money and freedom is the greatest way to change, may you be rich and continue to
    guide others.

  7. This is very attention-grabbing, You’re a very professional blogger.
    I’ve joined your feed and sit up for searching for extra of your great post.
    Additionally, I’ve shared your web site in my social networks

  8. Hello mates, how is everything, and what you desire to say regarding this piece of writing, in my view its truly awesome in support
    of me.

  9. Excellent post. I was checking continuously this blog and I
    am impressed! Very helpful info specifically the final part 🙂 I maintain such information much.
    I used to be seeking this certain information for a long time.
    Thank you and best of luck.

  10. Pretty section of content. I just stumbled upon your
    site and in accession capital to assert that I acquire actually enjoyed
    account your blog posts. Any way I’ll be subscribing to your feeds
    and even I achievement you access consistently fast.

  11. Excellent post. Keep posting such kind of information on your site.
    Im really impressed by your site.
    Hi there, You’ve done a fantastic job. I’ll certainly digg it and for my
    part suggest to my friends. I am sure they’ll be benefited from this site.

  12. I’m amazed, I have to admit. Rarely do I come across
    a blog that’s equally educative and interesting, and without a doubt,
    you’ve hit the nail on the head. The issue is something that not enough folks are speaking intelligently about.

    Now i’m very happy I stumbled across this during
    my hunt for something concerning this.

  13. Ahaa, its pleasant conversation about this article at this place
    at this website, I have read all that, so at this time
    me also commenting at this place.

  14. I’m really enjoying the theme/design of your website.
    Do you ever run into any internet browser
    compatibility issues? A couple of my blog readers have complained about my website not working correctly in Explorer but looks great in Safari.
    Do you have any solutions to help fix this problem?

  15. It’s not my first time to pay a quick visit this website, i
    am visiting this web site dailly and take fastidious facts
    from here all the time.

  16. I really like what you guys are usually up too. This kind of
    clever work and reporting! Keep up the superb works guys I’ve included you guys
    to my own blogroll.

  17. Today, I went to the beach front with my children. I found a sea shell and gave
    it to my 4 year old daughter and said “You can hear the ocean if you put this to your ear.” She put the shell to her ear and screamed.
    There was a hermit crab inside and it pinched her ear.
    She never wants to go back! LoL I know this is totally off topic but I had
    to tell someone!

  18. I’m extremely impressed with your writing skills as well as with the layout on your weblog.

    Is this a paid theme or did you customize it yourself? Anyway keep up
    the nice quality writing, it’s rare to see a nice blog like this one these days.

  19. Normally I don’t read article on blogs, but I wish to say that this write-up very pressured me to try and do it!
    Your writing taste has been surprised me. Thank you, quite nice post.

  20. I used to be recommended this blog via my cousin.
    I am not positive whether this post is written by
    means of him as no one else realize such exact about my trouble.
    You are wonderful! Thank you!

  21. I don’t even know how I finished up here, but I assumed this post was once great.
    I do not realize who you’re however certainly you’re going
    to a well-known blogger for those who are not already.
    Cheers!

  22. Pretty component of content. I simply stumbled upon your site and in accession capital to claim that I acquire in fact loved account your weblog posts.
    Anyway I’ll be subscribing on your augment or even I fulfillment
    you access consistently rapidly.

  23. You are so cool! I don’t believe I’ve read anything like that before.
    So nice to find another person with a few unique thoughts on this subject matter.
    Seriously.. thank you for starting this up. This web site is one thing
    that is needed on the internet, someone with a bit of originality!

  24. You could certainly see your expertise within the work you write.
    The world hopes for more passionate writers like you who are not afraid to say
    how they believe. Always go after your heart.

  25. I like what you guys are usually up too. This kind of clever work and reporting!
    Keep up the very good works guys I’ve incorporated you guys to
    my personal blogroll.

  26. Hello! I simply would like to offer you a
    big thumbs up for the excellent information you’ve got here on this post.

    I am returning to your web site for more soon.

  27. It’s a pity you don’t have a donate button!
    I’d definitely donate to this outstanding blog!

    I suppose for now i’ll settle for bookmarking and adding your RSS feed to my Google account.
    I look forward to fresh updates and will share this website
    with my Facebook group. Chat soon!

  28. Simply wish to say your article is as astounding.

    The clarity in your submit is just excellent and that i can think
    you’re an expert on this subject. Fine along with your permission let me to clutch your RSS feed
    to keep updated with coming near near post. Thanks 1,000,000 and please continue the gratifying work.

  29. Greetings from Carolina! I’m bored to tears at work so I decided to browse your website on my iphone during lunch
    break. I enjoy the knowledge you provide here and can’t wait to take a look when I get home.
    I’m shocked at how quick your blog loaded on my phone ..
    I’m not even using WIFI, just 3G .. Anyhow, good blog!

  30. I’m really enjoying the design and layout of your
    website. It’s a very easy on the eyes which makes it much
    more enjoyable for me to come here and visit more often. Did
    you hire out a developer to create your theme?
    Exceptional work!

  31. Good post. I learn something new and challenging on sites I stumbleupon every day.
    It will always be useful to read content from other writers and practice something from
    their websites.

Leave a Reply

Your email address will not be published.