Responsive Web Design is a huge movement in the web development world right now. Having one site that will automatically adjust to your device based on its display size is quickly becoming the norm. When I find myself on a website that hasn’t thought about their mobile experience, my face grows an automatic frowny-face. Thankfully, a lot of great html frameworks are giving us easy options to implement this type of development quickly and easily without adding unnecessary overhead into our clients’ budgets. The world is looking pretty swell for responsive.
But what about other aspects of automatic design change? Responsive design gives great thought to changes in layout based on size, but what about changes to design based on content? What if your website could react to the content it was loading and adjust its entire color palette to properly keep the color relationships as designed?
This lab project is a proof-of-concept of just that idea. This is a reactive design based around, in this case, an image. See this link for a working example. Click on the images to adjust the background color and text color automatically. The background color is generated by simply pulling out the average color of the image. The text color, in this case, is an automatically generated complimentary color with a complimentary luminosity.
If you were to look at a color wheel, the complimentary color would be the one directly across the circle from the color you start with. This is one of many forms of color relationships that generally works well in designs. There are many great tools online where you can discover all sorts of color relationships.
Luminosity is a way of talking about a colors brightness. If you think about an old black and white film, you know everything is actually in color, but you can’t see it. You can, however, see different shades of brightness. These shades (and tints) are part of a color all the time, but you don’t think about them unless you are seeing the color’s saturation removed. On the right is an example of two colors with their respective luminosities revealed below. For design purposes, changing luminosity is very important. In my sample page, I am offsetting the luminosity of the text from the background to make sure there’s always a good contrast.
That’s enough about color theory. Lets talk about code!
Here’s the class I am using to do the majority of the work in my sample page. The color class handles converting between different color modes (RGB, HSL, HSV, HCY) automatically so we don’t need to handle all that math ourselves. You can probably skip past most of this unless you’re into color math. It’s pretty neat stuff, but looks a lot harder than it is.
Now that I have the helper methods in place, lets look at the HTML.
The first function, getAverageRGB, uses html5’s canvas object to pull
out color information from the image. I’m really not confident in doing
this in a production environment. There are two main problems with it.
First, although I love the canvas object, it really isn’t everywhere
just yet. You’ll end up writing backups for this to work in older
browsers, and I’ve never been a fan of writing code twice.
there is some really strange behavior with browser cache. You see, the
canvas object won’t load images cross-domain, which means if you try to
use this with an external image from, say, Flickr, it will throw errors.
In my initial test, I had an image in the same folder as my HTML
thinking that would be just fine–it is on the same domain, after-all.
When I tested the page, it worked the first time, but after reloading it
threw a security error. I believe, though I haven’t fully tested this,
that when the page was trying to load the image from cache, it was
acting as if it were a different domain.
Edit: It turns out my mysterious cache bug wasn’t cache at all. I was trying to process the images too quickly, before they had fully loaded. I wrapped my code in a $(window).load function and everything is fine again.
In any case, the canvas method I’m using is just one of many. There are plenty of server-side methods of getting color information from an image.
At the bottom, I am setting up click handlers on each image. When the images are clicked, the clicked image gets passed to the updateColors function which does all the updating for the colors on the page. Inside this function we get the base color of the image, then apply a variety of transformations to it to derive the color palette below.
Obviously there’s a lot more that we could do here. If this were a full site, one could reasonably build the entire css color palette in a relational way to a single base color. For example, you could create a compound color relationship with shades and tints for highlight areas. All of these things would be coded as mathematical relationships. Then, when a new base color is set (via a new background image, perhaps), the entire site will update, but maintain its excellent color relationships.
I think there’s a lot of room for this experiment to grow into something really cool. Can you think of any other ideas of ways this could be used?
As always, the source can be found over on github.