Advanced CSS Links – Spice Up Your Links

By  on  

Remember the days where links were just a standard underline? Neither do I, thankfully. CSS allows us to add background color, text decoration, color swapping, and numerous other formats to denote links before and during hover/active events. We can even change the color of the link based on whether the user has visited the destination previously. Do these links really provide as much information with as much flare as they could be though?

One suave developer created a Firefox plugin called Link Alert. Link Alert analyzes a link's HREF upon mouseover to change your mouse cursor to a lock if the link takes you to a secure URL, to an Adobe icon if you are opening a PDF file, to a double box icon if the link will open in a new window, and so on. Wouldn't it be great if we could convey that to our website visitors without needing them to install a new plugin? We can, but why wait until they've moused the link to let them know what it is?

Using advanced CSS tactics and some free icons, we can make our links say a lot more about themselves.

The Files

PDF Icon (16px x 16px)

The Code

There are two ways to go about creating special links -- designating classes for each type of link or use a method that is NOT IE6 friendly. Since our goal is to enhance and not to ensure cross-browser capabilities, we will go the more dynamic, classless route which will be much easier to maintain. Also note that this could be done using JavaScript but isn't CSS so much easier to use?

Here's the CSS code:

a[href$='.pdf'] { padding:0 20px 0 0; background:transparent url(/graphics/icons/pdf.gif) no-repeat center right; }

The code is pretty self-explanatory. The $= directs the browser to match any anchors that end in ".pdf" (find all PDF files), pad the link 20 pixels on the right, and insert a small PDF icon. You can use this code for any extension, but I recommend doing this for JavaScript (.js), images (.jpg, .gif), new windows (you'd match "target$='_blank'"), PDF files (.pdf), email links ("href^='mailto:'"), and RSS feeds ("href$='whatever.xml'").

The Result

Link

Recent Features

  • By
    Being a Dev Dad

    I get asked loads of questions every day but I'm always surprised that they're rarely questions about code or even tech -- many of the questions I get are more about non-dev stuff like what my office is like, what software I use, and oftentimes...

  • By
    Conquering Impostor Syndrome

    Two years ago I documented my struggles with Imposter Syndrome and the response was immense.  I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions.  I've even caught myself reading the post...

Incredible Demos

Discussion

  1. Andrea

    This is ok in Firefox but – as you said – doesn’t work in IE6, because the latter doesn’t support the attribute selection in CSS.

    Unfortunately, this approach breaks in IE7 – precisely because IE7 *does* support the attribute selection!

    Indeed, if your link wraps over two lines, you’ll have an unpleasant surprise.

    I think the way IE works is as follows: for the background’s dimensions calculation, you will not have a slim box of the height of a line wrapping like a snake over different lines, but a single box that holds them all. As a consequence:
    + the background’s right will be the rightmost point of any of the lines involved (not of the last, as in Firefox);
    + the background’s height center will be the center of the height of all the lines combined (again, not only of the last);
    + however, the right padding will be added only to the last line;
    = Disaster: the image will display to the right of the block of text (not of your link’s last line) and somewhere centered between all the lines of the link (usually you’ll only see a small part of it at the right of the first line, covered by the link’s text).

    The same applies to IE6 if you extend this technique by using classes to mark the links you want to apply such a rule to.

    I met this problem a couple of years ago when I tried to implement exactly the same solution, and had to use an ugly workaround which would only work under certain conditions – which were met in the specific context pf my problem. Maybe somebody has a general solution for it?

  2. General solution to IE wrapping problem:

    Use CSS :after pseudo selector with the content attribute for browsers that support it, or use JavaScript to loop through the links and add the image.

  3. Andrea

    Dave,

    true. I was hoping for a solution that would work in IE6 and without javascript, but after all your second option would work fine in most scenarios, so as long as it isn’t critical to have the links properly ‘dressed up’, why not.

  4. surely you could use a {white-space:nowrap;} to avoid the problem above. It might make really long links and paragraphs containing them a bit ugly, so the solution is to not use long links :)

    i would see no special reason to dress up IE6 specifically. im all for progressive enhancement.

  5. Thank you for posting Dave, Daniel, and Andrea! The idea in this situation is to use CSS to enhance — these “spiced” up links aren’t meant as a necessity. Great solution too Daniel!

  6. Andrea

    David,

    it’s a pleasure!

    I’m all for progressive enhancement, too, but if a solution fails ‘ungracefully’ in an A-grade browser such as IE7, the term doesn’t apply.

    In my view Daniel’s – clever – solution may save the day most of the time but would prove unacceptable in still too many cases, as it means that a design constraint limits your editorial choice (in particular if you have relatively narrow text columns) – and as he said, where the rule applies the result tends to be a bit ugly (and sometimes maybe even *very* ugly :o))

    From this point of view, Dave’s :after solution seems more reliable: the following works in Firefox and doesn’t break neither in IE6 nor in IE7 (haven’t tried Opera or Safari, though):

    a[href$='.pdf']:after {content: " "url(/graphics/icons/pdf.gif)}
    

    Thanks to all for the tips.

  7. Thanks for the :after tidbit.

    One rule I have for designing my sites is that I don’t place links within content paragraphs. I place the conversion link after the paragraph to make it stand out, much like my example link.

  8. As well as Andreas’ :after tip you can also use :before , for example

    a[href$='.pdf']:before { content: url(/icons/pdf.gif); padding: 0 5px 0 0; }
    

    Also, as well as defining file extensions you can also distinguish links to individual websites;

    a[href*='youtube']:before { content: url(/icons/youtube.gif); padding: 0 5px 0 0; }
    a[href*='wikipedia']:before { content: url(/icons/wiki.gif); padding: 0 5px 0 0; }
    

    Now, can anyone tell me if it’s possible to have a default icon when all other rules fail?

  9. I use this technique on my website – it works in FF, Opera, Chrome, Safari but not in IE. As a temporary way round the problem, I have all the relevant CSS in an external stylesheet and then use a conditional comment to “reset” the style on each page (code below).

    This results in users who are not using IE (aka sensible users! :-) ) get the pictures and IE users (poor souls) have plain links… Not an ideal solution… but sometimes it’s not an ideal world sadly. I have to disagree with Andrea though. IE wont be an A grade browser until Microsoft ensures that IE complies with standards that have been in place for years!

    Elliott

    Code:

    #leftcolumn a.exlink
    {
    border-width: 0px;
    text-decoration: none;
    padding-right: 0px;
    background: none;
    }

    #leftcolumn a.pdflink
    {
    border-width: 0px;
    text-decoration: none;
    padding-right: 0px;
    background: none;
    }

    #leftcolumn a.doclink
    {
    border-width: 0px;
    text-decoration: none;
    padding-right: 0px;
    background: none;
    }

  10. Your Result are not longer shown and it looks like a missing GIF Image – maybe you’d changed your Theme or cleanup (to clean) your image folders?!

    It’s repaired in seconds and I’m sure you interested in?!
    Hey, take it just as a small hint ‘from geek to geek’ ;-)

    All the best from Germany and “rock your blog”
    (with my honestly respect)

    yours
    freuter

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!