Showing File Types in Links

Meme image showing a fake X-ray of a skull with a small brain alongside a link with no file indicator; a similar image but the brain has dots of light alongside an link with a file indicator; the same but with a glowing brain alongside a link with a text indicator; a brain shooting light beams alongside a link with a file size indicator. Links to files can be a surprise for users, especially those who cannot use, do not notice, or do not have the status bar to show a link destination. Some users may appreciate knowing a link points to a file, sometimes even a particular file. For links with the download attribute, it just seems nice to warn them.

Following are some techniques…

Common

I see this little CSS developer convenience touted every now and then:

a[href]::after {
  content: "";
  display: inline-block;
  height: 1em;
  width: 1em;
  margin-left: 0.25em;
  vertical-align: center;
  background: center/contain;
}
a[href$=".pdf"]::after {
  background-image: url(/img/pdf.png);
}
a[href$=".doc"]::after {
  background-image: url(/img/doc.png);
}
a[href$=".docx"]::after {
  background-image: url(/img/docx.png);
}
a[href$=".zip"]::after {
  background-image: url(/img/zip.png);
}

For a quick indication of the type of file in a link, this is handy. It means authors who maybe only use a WYSIWYG never have to think about it; the CSS just does the work for them.

This has some drawbacks, though:

Enhanced

An alternative pattern, however, can wipe those issues away:

a[href$=".pdf"]::after {
  content: " (PDF)";
}
a[href$=".doc"]::after {
  content: " (Microsoft Word)";
}
a[href$=".docx"]::after {
  content: " (Microsoft Word)";
}
a[href$=".zip"]::after {
  content: " (ZIP archive)";
}

Right out of the gate you get:

It still has some drawbacks:

Usable

Potentially an even better solution is this:

a[href]::after {
  /* Yeah, do nothing */
}

And then in your links themselves, do this:

<a href="foo.pdf">Annual Report (PDF, 25MB)</a>
<a href="foo.doc">expense report (Microsoft Word, 250KB)</a>
<a href="foo.docx">medical leave form (Microsoft Word, 250KB)</a>
<a href="foo.zip">Doom installer (ZIP archive, 1.44MB)</a>

It brings you the following benefits:

Sure, it has its drawbacks:

That can be a lot to ask for some folks, I know. That is not me being snarky; it can really be a problem for some authors or organizations, particularly when not technical. Provide training and documentation for those cases. Give them the skills to be successful.

Example

Visit the pen directly if the embed does not load.

See the Pen Showing File Types in Links by Adrian Roselli (@aardrian) on CodePen.

Wrap-up

For some audiences any one of these approaches may be too much. It may not be a good fit for an intranet or for a file repository. None of these are probably a good idea within navigation, and pages full of links to the same file type or even size may not warrant the extra text. Links can get verbose for screen reader users or difficult to use for voice control users.

The point is — test. Test with the users of the site or application where you want to use one of these techniques.

Similarly, you can apply these techniques (ideally the last one) to the target attribute, specific domains, HTTPs versus HTTP links, and so on.

Update: 14 October 2020

While I recommend against using CSS generated content to embed an icon (for reasons outlined above), in the future it can be less awful than using a background image because it will at least allow for alternative text: Alternative Text for CSS Generated Content

One Comment

Reply

Thanks for hashing this out, Adrian. So many points I hadn’t even considered. I especially love the last suggestion (usable), which is what I’ve been doing during my day job for 2 years now, even though it’s not “pretty” or “elegant”. However, it’s been an important step to help our users since we often have lots of downloads available.

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>