The Zen attachment
This is a small story about the beauty of simple solutions. It is the story about an elaborate problem set where each solution gets more complex, and doesnt really solve the main issue. In the end a stroke of genious solves the problem with only a 16 byte size increase. Keep It Simple Stupid
The problem
I was working on a list of items which each might have an icon to indicate that a file was associated with the item. The icon is the familiar attachment paper clip as seen here:
![]()
Now, each of the items in this list may or may not be selected, where a selected state means a change of background color. The problem with this icon is that it is black and transparent, making it invisible if the background color changes to black, and very hard to see for dark colors in general.
The problem gets further complicated as I have to work with css system colors. System colors are a beautiful tool, with just as many bugs as advantages. The system colors introduce a total uncertainty on what color is actually used. The usualy color scheme on most window managers is black on white, or at least dark on light. However there is no guarantee, and as it turns out, no way to find out.
The possible solutions
Javascript
Since javascript is an integral part of this little application, i had no problem using javascript to find a olution to this problem.
First off, I tried to see if it was possible to read the hex color of the background color from the clients browser. This would give me the advantage of being able to use color theory and calculate an exact opposite color for maximum contrast.
The script I would use for reading a css style applied by an external stylesheet is a snippet I got from Philipp Feigl (philipp.feigl@gmail.com). It enables me to read the exact value applied in the stylesheet. Upon running this script, all I got for background-color of the element in question was ‘Highlight’, which is the css system color I used. The script runs fine, it just turned out that i could not extrapolate the hex color of an element like that.
CSS
Next I though about setting a different background color based on the selected state of the element. But not knowing if the selected state would be dark or light left me with the exact same problem as before. I might simply end up choosing an icon color identical to the background color, rendering the icon invisible.
Image editing
So I fired up photoshop and took a good look at the icon:
![]()
Now, I know that if I add white to the image, it will be visible in any background color, light or dark, since there is always one of the two colors in my image with a high contrast to the background. However, looking at dropshadows just led to the conclusion that there is no way to make a shadow look exactly like the original clip because the original will always block the shadow somewhere. So a white dropshadow was out of the question as well.
The stroke of genious
Wait a minute! Doesnt this clip look a bit symetrical to you?
It looks as if I could fit another clip inside the transparent parts of the black clip.
After fumbling around a bit with it, it turned out that a 180 degree rotation was all that was needed. What i ended up with was a Yin and Yang resembling attachment icon where the black and white complement each other perfectly without ever blocking out the other one.
The solution looks like this enlarged (on grey background to make you able to distinguish the two clips):
![]()
And here a little demonstration of a color change from black to white with the resulting icon:
And just like that I had solved my contrast problem. The resulting icon went from 7×14 pixel to 8×14 pixel in dimensions, and from 62 byte to 75 byte in size. Keeping it simple really does work.
on January 30th, 2007 at 5:26 pm
Yep, I have seen tricks like that used before.
Your solution even works on colors
http://www.chrisbenjaminsen.com/temp/paperclip.gif
on February 13th, 2007 at 4:12 pm
This is a solution very similar to the way photoshop’s colorpicker uses (or used to? I havn’t used that program for a while) a black circle next to a white circle as a cursor while hovering over the color-gradient.