My web color scheme generator is currently set up to reflect my own biases. The results are almost always readable, even for people with various forms of color-blindness, but who’s to say that my way is best?
Well, me, of course, but once or twice a year I’m willing to admit that I might be wrong about something. In recognition of that possibility, I’ll explain the syntax for the mini-language I created for the generator.
Let’s start with the default ruleset:
base: r=[0,100]; g=[0,100]; b=[0,100]
back: base; h+[-15,15]; s=[0,10]; v=[90,100]
side: base; h+[-90,90]; v=[75,85]
text: base; h+[-30,30]; s=[90,100]; v=[0,20]
head: back,side; s=[90,100]; v=[20,50]
link: back,side,text; s=100; v=40
visited: link; v-10
The format is “label: operation [; operation …]”; that is, a name for the color that’s being generated, followed by one or more color changes, processed left to right. A simple, self-contained rule would be something like “green: #00ff00”, which would define the color named green to be, well, green.
Rules can refer to previously-generated colors by name, copying them and then modifying one or more color channels: “yellow: green; r=100”. Additional colors in a rule are linearly interpolated with the current color. If I had defined red to be #ff0000, then the color produced by the rule “red,green” would be #7f7f00, which is definitely not yellow. Adding colors rather than interpolating them would be interesting, but I haven’t implemented it yet because I think interpolation is more useful for creating contrast on a web page.
That’s why I defined yellow to be a copy of green with the “r” channel set to 100%, which is my sneaky way of introducing channel operations. Six different channels are supported, representing the RGB (red, green, blue) and HSV (hue, saturation, value) color spaces. Hue can be modified in a range from -360 to 360 degrees, while the others range from 0 to 100%. They are of course represented by the variables r, g, b, h, s, and v.
You can do three things to a channel: set its value to some number (=), add to its current value (+), and subtract from its current value (-). This number can be selected randomly from a range, such as “r+[30,60]”, which adds a number between 30 and 60 to the red channel. If the result of the operation is too big or too small, it’s automatically set to the nearest valid number.
With that in mind, the default ruleset (loosely based on one in Kasper J. Jeppesen’s ColorDesigner Mac application) breaks down as follows:
So, how would you generate light text on a dark background? I hoped you’d never ask:
base: r=[0,100]; g=[0,100]; b=[0,100]
back: base; h+[-15,15]; v=[0,30]
side: base; h+[-90,90]; v=[15,25]
text: base; h+[-30,30]; v=[80,100]
head: back,side; v=[50,80]
link: back,side,text; v=60
visited: link; v+10
I’ve left out the saturation adjustments, and extended the brightness range for the background (0-10% would just look black most of the time).
Of course, you don’t have to generate all of the colors randomly. I usually force the text color to black, for instance: “text: #000000”.
Manually entering colors this way is a good way to tinker with an existing web site. After a physically painful visit to cut on the bias, I played with her color scheme and attempted to persuade her that #bb2222 on #6699ff would be easier on the eyes than #ff3333 on #6699ff. I still don’t like it, but at least it doesn’t give me a headache. No luck, though.