Last Updated: May 30, 2016
·
3.846K
· artinruins

Add Icon to External Links BUT not Anchors that contain an Image

The Problem

I had a site that styled external links with some fairly straightforward CSS. You've seen this pattern before, I bet. For illustrative purposes, this is it:

a[href^="http:"]:before:not([href^="http://www.thissite.com"]), 
a[href^="https:"]:before {
    ...icon styles...
}

This worked fine, but there was a problem. The client added anchors around images, which is perfectly acceptable (and something I should have expected) and so, when the image was nice and large, it had an icon to the left. It didn't look good, and I agreed. I had to fix it.

CSS won't provide a Solution

Problem is, there is no CSS selector that can help me exclude this style when an a contains an img. The selector a > img or a + img will style the img, which won't help me. What we really need is a a < img selector, but that doesn't exist (even Chris Coyler wishes it so, with no luck.

Luckily, we have jQuery that can help.

I was surprised that I was not able to turn up someone else who had done exactly what I was looking for. After some digging, some testing, and some investigation into the nice has() jQuery extension, I settled upon this solution (compatible with jQuery 1.1.4 and up):

/* Add rel="external" to links that are external (this.hostname !== location.hostname) BUT don't add to anchors containing images */
$('.text a').each(function() {
    // Compare the anchor tag's host name with location's host name
    return this.hostname && this.hostname !== location.hostname;
}).not('a:has(img)').attr("rel","external");

NOTE: I use '.text a' to apply this attribute only to anchors in the main content area, which avoids looping through links in the navigation and other places that I do not want to icons to apply to.

Instead of adding a class, I decided to add an attribute that would prove useful for SEO and semantic. I then style this class with a simple CSS attribute selector:

a[rel=external]:before {
    ...icon styles...
}

I also decided against adding target="_blank", though I easily could have. The reason was that the client has a CMS with a WYSIWYG editor, and so they have control over adding a target or not adding it. It was better in my mind to leave those things in their control and use jQuery to automatically do things that enhance the experience for the end user.

3 Responses
Add your response

Hello, i'm having some issue with your nice script.
I tried to force (via Inspector) a rel="external" in one of my external links and the css class successfully worked.

I think that should be an error in your jquery script, or maybe something different came up with latest jquery releases, so the code doesn't add this rel attribute to 'a' elements..

Do you have any suggestion for this problem?

btw Thanks a lot for your contribution, as you said i can't find many solution on the web!

Pietro

over 1 year ago ·

I'm not sure about what the script is doing for you that it is not supposed to do, subfighter3. The script was written to specifically add rel=external to anchors, so, it is not an error that it adds them to <a> elements. Are you saying that it no longer works? Make sure that if you use a different classname for your container element, that you change the jQuery. I use .text in the $('.text a') jQuery each() but you may use something else.

over 1 year ago ·

Actually I solved my problem. My issue was caused because I wanted to have $('a') without any other selector to have the external link icon also in footer.

in the end I added more specific selector because i'm using Squarespace with relative links only.

btw in the end works fine, thank you for your nice solution!

over 1 year ago ·