How many times have some of you tried to add an icon image to an anchor tag (link: <a>) or make some other random image part of that link and have had one-heck-of-a-time trying to align the text of the link and the image (<img>) tag?
I know that I have (especially when each browser treats the vertical aligning differently)…
Well here is the better way of aligning them that will make your life at least 10 times easier using 0 img tags and 1 anchor tag with CSS styling…
Many times (especially in today’s web development) you may want to add icons to your links to make them more readable or bring attention to them. Moreover, many large sites have adopted this “iconified-links” pattern to make life easier: www.linkedin.com, www.yahoo.com and www.facebook.com to name just 3. Well it would be good to have them aligned to make life easier!
Example: Yahoo! Front Page
If you hover over either the link text or the icon, you will see that they are part of the same link.
Moreover, if you inspect the link, you will see that there is no IMG tag.
If you look at the source of the where the image is coming from you will find this image… it’s a giant “sprite” (or collection of images) that represent all of the icons they use.
The Classical (Wrong) Way…
Say that you wanted to try and reproduce this type of behavior with a Logout button on your site. You also want to have some fancy logout icon that you want displayed along with it.
We are going to use the “door_in” icon () from the Silk Icon collection of Mark James’ site famfamfam.com. Mark did a beautiful job constructing the 1000 icon set, and I would recommend to anyone to use his icon set with his permission! (See Below)
So now that we have our logout link and icon, it’s time to align them like Yahoo! has it (exactly centered). Now there are two ways that using the old way of thinking to go about this…
Ok, so Option 1 is completely stupid. Not only do you have to worry about aligning the two elements, you also need to make sure that the link meta-data is the same for both links! So we will automagically rule out Option 1.
Option 2 is a little bit better, so we will work with that. All right, we’ve used it and now its time to display it in our browser…
Ok so we already added a ‘border=”0″‘ attribute onto our image tag because a useless border is added when you stick images inside links, and now we see that the alignment is off for our image.
So, we adjust it to align=”center”… align=”top”… align=”bottom”… “middle”. Still not the results we are looking for, so we adjust the line-height the font-size, etc, etc… and we end up jumping through hoops just to get them align in IE, then we switch over to Firefox. WTH? Firefox doesn’t even align close to what IE shows!
Now you spend the next 3 hours trying to get those to align perfectly in every browser, but now what happens when your link is long and the lines wrap? Ahhhhhhhhhhhhh!
You’ve just lost all sense of indentation and you have a bad solution that can’t be generalized (not only that but any space you put between your text and the img tag leaves a space which gets put into the link as a useless underline ‘_’)!!
Well, read on to stop you from pounding your head against the wall…
The Correct Way…
When I was staring at Facebook’s “iconified” solution I noticed that there was no image tag used at all; in-fact, there was no image information period!
I then looked a bit deeper and found the secret lines in their CSS code that does the magic for you.
background: transparent url(/images/icon.gif) scroll no-repeat left center;
padding: 2px 0px 2px 20px;
That’s it all-of-a-sudden the alignment works and works in all browsers!!! Even indent information is preserved when the text wraps!!! Yay.
First let’s talk about the attributes we define on the CSS background property. It happens to be the shorthand version of about 5 other CSS commands (you should be using the CSS shorthands)
background: [background color] [background image] [background attachment] [background repeat] [background position];
This operates the same way as the CSS background-color property; here, you can specify the background color (transparent is a valid color and is good for when your icons have transparency layers in them) that your element will have.
This operates the same way as the CSS background-image property; this is where you specify any background images. Valid entries are url(/path/to/image) and none. **This is where you define your icon image location
This operates the same way as the CSS background-attachment property; this is where you specify if you want your background to scroll with the page or not. Valid values are scroll and fixed. “Fixed”is rarely used; it represents truly absolutely fixed position items. **We will use “scroll” for our purposes.
This operates the same way as the CSS background-repeat property; here, you specify if you want your image repeated at all, repeated along the x-axis, repeated along the y-axis or repeated along both the x and y axis. Valid values are repeat, no-repeat, repeat-x and repeat-y. **For our iconified purpose, we don’t want any repeating so we will use “no-repeat”.
This operates the same way as the CSS background-position property. This represents the position that you would like to place the background-image from the top-left-corner of your element. This can be represented by either two values or one value.
If you use the two valued version, the first value represents the distance from the top left corner along the X-axis. Likewise, the second value represents the distance from the top left corner along the Y-axis.
If you use the single valued version, the only value represents the distance from the top left corner along both the X and Y axis.
Valid position are: physical distance (3px, 2pt, 1em, 50%, etc) or relative values: top, bottom, center, left, right. **We will use the 2-valued version:”left” as our X position and “center for our Y position
Padding is another short hand and doesn’t really need to be explained that much.
padding: [padding-top] [padding-right] [padding-bottom] [padding-left];
These values all depend on how big our icon images are and how large our text is.
For our example (18px by 18px icon) in normal text, a 2px top and bottom padding and a 20px left padding should do nicely.
Our Example In Use…
So now all we have to do is make a smart CSS class that has background and padding set properly…
Now we can just add class=”iconified” to any element (not just links)
Here is the result!
What happens if it wraps? (well, it works even more funny in IE; you need to add “display: block” to turn your anchor from an inline element to a block element for this to work properly)
There are many uses for combining HTML elements (div, span, td, a, etc) and the CSS background & padding properties besides just fancy icons: fancy bullets, pagination, borders, etc, etc.
Go and experiment with different backgrounds with different positions!
One thing to watch for: png icons have trouble with transparency in IE6 and below and the Twin Helix HTC fix (AlphaImageloader) will need to be applied for elements that use them. My advice is to just save it as a gif and see if the quality is reduced that much.