Adding an icon to a headline or hyperlink

The attached pdf document shows how to add an icon to the left of a heading or link element using CSS.

In a nutshell, given that we have the following markup :

<li><a href="..." title="printer-friendly copy">Print this article</a></li>

Using padding to push the text to the right

We would like to snug in the image of a printer on the left-hand side of the text. For that, we will set the GIF image as background-image of the link, and push the text to the right with some padding (reminder : background images and color are still visible within the padding, but not in the margins).

Since we don’t have a class or id attribute to use for easily targetting that one link that is part of a list of links, we can use an attribute selector.

a[title*="printer-friendly"] {
padding-left: 30px;
background: url(images/printer.gif) no-repeat left center;
}

A word on attribute CSS selectors

Internet Explorer 6 does not support attribute selectors, but IE 7 does.

People often confuse the ~= operator with the *= one when using attribute selectors.

Selector What it does
p[class~="warning"] Use ~= for any attribute that accepts a space-separated list of words, such as the class attribute. This selects paragraphs that belong to the warning class, but may also belong to other classes as well.
p[class="warning"] This selects paragraphs that only belong to the warning class, and no other class.
a[href^="http"] This is a substring matching attribute selector. It selects links that have a href attribute that begins with letters http.
a[href$="pdf"] This is a substring matching attribute selector. It selects links that have a href attribute that ends with letters pdf.
a[title*="printer-friendly"] This is a substring matching attribute selector. It selects links that have a title attribute that contains these letters in that order : printer-friendly.

What if the link extends over several lines ?

Smaller text size

Larger text size

If the text extends over several lines, we may want to position the background image — the icon — so that it remains next to the first line of text, always. To position a background image relative to the text size inside a given element, we use em units. If within a given element the font-size is set to 12 pixels, 1 em is equal to 12 pixels, for that element. If within the same element the font-size is set to 14 pixels, 1 em is equal to 14 pixels, for that element.

Do not use pixels to position the background image, because the user may resize the text (see the two screenshots on the right), so you do not know for certain what size the text is within the element, in pixels. However, the size of the GIF image is fixed, and so is the padding that makes room for it on the left.

a[title*="printer-friendly"] {
padding-left: 30px; /*width of the GIF or png image*/
background: url(images/printer.gif) no-repeat 0em 0.5em;
}

Fine-tune the position of the icon by playing with the second em value, change it from ~0.3em to ~0.5em, until you like what you see.

UPDATE : There was a typo in the attribute selector table, and I corrected it on February 27th, 2007. The substring matching attribute that selects an attribute that begins with a given substring uses the ^= operator, not ~=. Sorry about that. Doh.