Unobtrusive, cross-browser method to add icons to links
There are lots of examples of using CSS to add filetype icons to links, but they all rely on advanced CSS selectors, which Internet Explorer 6 doesn't support. If you're looking for a cross-browser method of adding filetype icons to links, you have a couple of choices: you can add a class name to all of your links and target that class name with CSS that IE6 can understand; or you can let Javascript add the links dynamically based on the extension it finds at the end of each URL. The class name method is fine if you don't mind adding the class to all of your links in your HTML, but the Javascript method will figure out which links get which icon automatically.
The Javascript/jQuery method
This uses my favorite Javascript library, jQuery; you'll need to include the library in your document, and then either put the icon-adding code in another file you include, or put it inline with your HTML. It's good practice to put all your jQuery code inside$.ready(), to be executed when the document is ready to be manipulated, but I've left that part out here for brevity.
Round 1: Because jQuery supports CSS1-3, you can mimic the CSS rule that wouldn't work in IE6:
$('a[href$=".doc"]').
css({
// use paddingLeft instead of padding-left;
// jQuery (and Javascript) use camelCase
// for CSS attributes instead of hyphenation
paddingLeft: '18px',
background: 'transparent url("word-doc.gif") no-repeat center left'
});// first, create an object
// that contains information
// about how file extensions
// correspond to images
var fileTypes = {
// extension: 'image file'
doc: 'doc.gif',
xls: 'xls.gif',
pdf: 'pdf.gif'
};
// then, loop over the object
// using jQuery's $.each()
$.each(fileTypes, function(extension,image) {
$('a[href$="' + extension + '"]').
css({
paddingLeft: '18px',
background: 'transparent url("' + image + '") no-repeat center left'
});
});var fileTypes = {
doc: 'doc.gif',
xls: 'xls.gif',
pdf: 'pdf.gif'
};
// this is like $.each() above, except
// it iterates over the matched elements
$('a').each(function() {
// get a jQuery object for each anchor found
var $a = $(this);
// get the href attribute
var href = $a.attr('href');
// get the extension from the href
var hrefArray = href.split('.');
var extension = hrefArray[hrefArray.length - 1];
var image = fileTypes[extension];
if (image) {
$a.css({
paddingLeft: '18px',
background: 'transparent url("' + image + '") no-repeat center left'
});
}
});Taking it further
You can also add a different icon to external links, and only add filetype icons to internal links:var fileTypes = {
doc: 'doc.gif',
xls: 'xls.gif',
pdf: 'pdf.gif'
};
$('a').each(function() {
var $a = $(this);
var href = $a.attr('href');
if (
(href.match(/^http/)) &&
(! href.match(document.domain))
) {
// use a special image for external links
var image = 'external.gif';
} else {
// get the extension from the href
var hrefArray = href.split('.');
var extension = hrefArray[hrefArray.length - 1];
var image = fileTypes[extension];
}
if (image) {
$a.css({
paddingLeft: '18px',
background: 'transparent url("' + image + '") no-repeat center left'
});
}
});$('a') to $('ul#fileList a').
Resources
- There are nuances to the CSS you'll want to apply to your links; the above is just an example of something that may or may not work for you. Read more here about how to style the links so your background images appear as you want them to.
- If you're using transparent PNGs for your background images, iepngfix will save the day.
- famfamfam has some great icons available for free under the Creative Commons Attribution 2.5 License.
The class name method
In case you were wondering ... First, put a class name on the link:Word Document
a.word-doc {
padding-left: 18px;
background: transparent url('word.gif') no-repeat center left;
}11 comments
That said, if you are already using jQuery on your page for something else (and more and more often, I am), that becomes less of a consideration. And there are a lot more people using IE6 than there are people without Javascript enabled, so I think the tradeoff there is fair.
Thanks and great code!
if ($a.children('img').size()) { return; }
This will prevent the rest of the function from running, so the background image won't be added.
How would one go about getting this to work for mailto links?
Thanks!
This is how it looks on a test page: http://www.michael-van-laar.de/fileserver/diverses/icon-bug.png (Picture 1: CSS method in Firefox; picture 2: Javascript method in IE 6)
Since I’m not very familiar with Javascript yet, I don’t have an idea, if and how this could be fixed. Any ideas?