Use HSL Gradients to Dynamically Set Colors for Emotional Impact

March 27th, 2018

A Use Case for Dynamic Coloring

I'm a huge fan of electronic dance music. When I was getting into it, I realized there were too many genres to accurately identify what I actually enjoyed. Literally 200+ of them, and many quite distinct from one another. Some genres were more chill, others more lively, and the genre names were almost universally meaningless to me as a newbie to the scene. I had access to an app that told me all the EDM shows coming to town, but the DJ names were also pretty meaningless to me. With a few exceptions, DJs have pretty limited name recognition. So every time I went to a show, it was a crapshoot whether I'd really enjoy myself.

After enough of this, I decided to solve my own problem by creating an app called Plurview, which combined the events list with some analysis. I narrowed the genres to a handful of archetypes like "House," "Big Room," "Trap," "Dubstep," "Trance," and "Bass Music" and started plugging in the artists I knew would fall snugly into those categories. Then, I built an algorithm to sort artists I didn't know based on factors like who they collaborated with and what genres they identified for themselves as part of their artist metadata around the web.

Narrowing down to 6 archetypes allowed me to play with primary colors for what type of music I could expect from an artist. Using gradients, I was able to describe the variety of music I could realistically expect from them, and to what degree based on more or less of a color. By fiddling with saturation, I could make the colors more vibrant or more washed out- for instance, based on measures of musical intensity. And then I made them lighter or darker to express more of the mood of the music to expect.

I was able to do this by calculating numbers to describe various aspects to an artist, and then mapping those numbers to values in an HSL color declaration. This had an exponential effect on the amount of information I could convey through color- far beyond the usual red/warning, green/success conventions we use in UI design.

What is HSL color?

HSL is a pattern for generating colors based on Hue, Saturation, and Lightness. This is a somewhat rare pattern, and it usually takes a back seat to Hex color codes (#000000 to #FFFFFF) in front-end design, or RGB(A) values that blend color with opacity. Rendering colors programmatically with HSL is useful for specifying where on the color spectrum it should fall, while letting the computer handle the rest.

What are HEX and RGB(A)?

HEX and RGB(A) are basically the same thing except for the (A) part, which affects the color's opacity. Red, Green, and Blue (plus Alpha for transparency) combine in values up to 255 for the colors and up to 1 for opacity, making basically any color imaginable. HEX is a quick shorthand for RGB: it combines a pair of hex digits for each color (as in, #FF equates to 255 in hex math), so pure white #FFFFFF is the same as rgba(255, 255, 255, 1.0). So HEX is a bit more efficient to write out- especially considering you can further abbreviate colors pairs in HEX if each pair is the same- #AABBCC in other words can translate to #ABC.

Knowing off-hand what some of these values adds up to can be useful for coding CSS on the fly because there is ample tooling to pick up color values with an eyedropper and paste them around. When it comes to letting an algorithm do the work though, HEX and RGB(A) are less than intuitive for expressing the emotional value of a color.

Why use HSL instead?

Designers tend to memorize a few set HEX or RGB(A) codes, and otherwise use color-pickers to manually select different shades fitting a brand palette or other specification. Services like Paletton can help in terms of providing color suggestions, but ultimately a person has judge and set values for use in the wild.

What if we took more of a centaur-style approach? Human head/horse (machine) body: give the computer a general idea how values match up to colors (as a proxy for sentiment), and let the machine handle the details.

Using HSL, a designer can assign intuitive value judgments to data analysis on 3 dimensions. Maybe it starts with green/red- a positive or negative value judgment. But HOW positive? HOW negative? Is it dull or throbbing (Saturation)? Well-supported or speculative (could be lightness)?

Now, magnify that by the rest of the rainbow. Then, consider the fact you can shift to multiple colors within a gradient. Finally, how about making predominant data occupy a greater portion of your gradient?

Once you establish a basic visual language in terms of how you're applying color values, a user can intuit a thousand words with a glance at a color bar. Think of this as a decision engine for whether a data point is worth further exploration: does this spectrum appeal to my needs? What about then sorting data by color? The possibilities are endless.

HSL values and emotional impact

Color values can express a range of emotions- "this product is HOT" / "our company is COOL"- and designers spend a lot of time picking them out manually, by feel. Computers don't struggle to understand how much red, green, and blue go into making yellow but designers do. Designers don't struggle with understanding emotions- at least not as much as computers do- and our intuition allows us to judge the meaning behind numbers we crunch.

A quick description of how HSL values work:

Hue- A number from 0 - 360, indicating its place on a color wheel. This is the general vibe of your color- a cool blue at hsl(200, ...), a warm magenta at hsl(310, ...), so on.

Saturation- A number from 0 - 1, which affects how vibrant your color will be. S values closer to 0 will come out more grey.

Lightness- A number from 0 - 1, ranging from black at 0 to white at 1.

Top value (in parens) is HSL: the first parameter is a color value- 99 for green, 0 for red- and only the saturation and lightness change. The bottom values are the HEX codes. It's less than intuitive to find patterns for predicting the end result.

Using HSL values in a gradient

After mapping out how your data relates to relative values in HSL, you can drop them into a CSS gradient the same as if they were HEX or RGB(A) colors:

linear-gradient(to right, hsl(348, 34%, 58%) 0%, hsl(348, 14%, 34%) 100%})

Note the 0% and the 100% after the HSL color declaration: these percentages refer to the point on the gradient at which your color will show its declared value. If you're combining two computed colors and weighing one more heavily in your gradient than the other, you'll have to account for where they'll peak rather than what percentage of the gradient you'll want them to occupy.

Brute-force gradient setting in React (example)

Here's a very simple example of setting these values to appear on the fly- brute force in the sense of applying them as inline CSS. Programmatically setting HSL as part of your component's state allows for dynamic gradient updating as part of your app, with the fewest moving parts in terms of stylesheets.

div style={{ background: `linear-gradient(to right, ${this.state.hsl})` }}

Consider storing gradient values alongside your data on the back-end in order to save processing time when rendering your data.