Skip to content

A podcast for those who design, develop and run websites.

Boagworld is the blog of web strategist Paul Boag who lives in the heart of rural Dorset (hence the cows). He produces a weekly podcast with UX consultant Marcus Lillington on building and running websites. They also run the web design agency Headscape.

Latest Shows

216. Thanks for all the fish
This week on Boagworld: Chris Coyier talks CSS and more, we say goodbye to the boagworld podcast and ask what can you listen to now?
215. Web Directions
This week on Boagworld: Emerging trends at Web Direction @Media, playful web design and death to design by committee.
214. When to hire a web designer
This week on Boagworld: When to hire a web agency, user testing on disposable websites and a need for speed.
213. Getting all emotional
This week on Boagworld: Stephen Anderson on emotional design, I review the iPad and we talk fonts, flash and fotos.
212. More skills to learn
This week on Boagworld: 5 new skills every web designer needs to know and how to be inspired while maintaining focus.

or view all shows

Have your say

Become a part of the Boagworld community...

External Links and new windows

Posted in Tech/Development on: Tuesday, January 31, 2006 by Paul Boag

Not long ago I shared some advice on handling links within your web pages. Today I want to cover linking to external sites. However, be warned, this is not a normal boagworld.com post… it contains code!

27/07/06: I have finally got around to updating the below to reflect feedback I have received via the comments. Thanks to everybody who has contributed.

What to do with links to third party sites has always an area of debate. The purists argue that the practice of opening new windows when linking to external sites is evil and that if wish to, they can do so themselves. However, if you have ever sat in on a session you quickly learn that simple things like launching a link in a new window is beyond many users. Furthermore, with so many bad sites around you cannot always rely on the back button to return the user to your site. Of course, at the end of the day these kinds of debates are redundant because if the client demands it, you will have little choice in the matter.

The golden rules of new windows

Whether you like it or not sooner or later you will have to open external sites in a new window. The trick is to ensure that this link doesn’t make your site break WAI guidelines on accessibility or invalidate your code.

Accessibility

The first problem relating to accessibility is relatively easy to solve. The guideline in question states:

Until user agents allow users to turn off spawned windows, do not cause pop-ups or other windows to appear and do not change the current window without informing the user.

The trick to complying with this checkpoint is to "clearly inform" the user that a new window is going to open. I recommend doing this in two ways. Firstly, assign the link a title tag telling the user the new window will open. Secondly, because you cannot rely on the user hovering over a link before clicking, add an icon after the link showing them something different is going to happen.

The issue of validation is a bit trickier. Normally to launch a link in a new window you use the target attribute. Unfortunately, this attribute is on the way out and will more than likely invalidate your document. Ensuring that your is valid now and in the is good practice for numerous reasons that I won’t go into here (if you want to know more about validation read my post on the subject). Sufficed to say that using the target attribute is not the answer.

Flexibility

What if your client changes his/ her mind in the future? Do you really want to be going through potentially thousands of pages altering all of the links? What you need is a solution that manages all of these links centrally so that by changing a few lines of code you can change the behaviour of all of them at once.

A neat little solution

If Jeremy Keith has taught me anything, it is that scripting is great for this kind of stuff. In three easy steps, you can create external links that open in a new window while still being accessibility, valid, and flexible. Here is how:

Step 1: Semantic code

Remember we might want to change our minds about spawning a new window later so no target attributes or title tags talking about opening new windows. Each link to an external site will simply read as follows:

<a href="http://www..co.uk" class="">Best web company ever!</a>

All I have done is say this links to another website with the class="", other than that it’s an ordinary link.

Step 2: Apply the

The JavaScript function below does the following:

  1. Looks at all of the a tags on a page searching for those labelled ""
  2. Changes the class of those tags to "newWinStyle" (I’ll explain why later)
  3. Adds "(new window)" to the end of the title tag so users know it is going to spawn a new window
  4. Attaches an "onlick" event to those links so that when they are clicked it opens in a new window.

// Opens a link in a new window when class =
function doPopups() {
if (!document.getElementsByTagName) return false;
var links = document.getElementsByTagName("a");
for (var i=0; i < links.length; i++) {
if (links[i].className.match("")) {
links[i].className = links[i].className + " newWinStyle";
if (links[i].title == "") {
links[i].title = "(new window)";
}
else {
links[i].title = links[i].title + " (new window)";
}
links[i].onclick = function(e) {
if(!e)e=window.event;
if(e.shiftKey || e.ctrlKey || e.altKey) return;
window.open(this.href);
return false;
}
}
}
}

If JavaScript is disabled the link still works but opens in the same window. That is why the title tag is applied in JavaScript. If the "new window" message was added in the html it would cause confusion if JavaScript is disabled and the window spawning didn’t happen.

Step 3: The

In your CSS file, you can now create a new style for "newWinStyle" and make external links look however you want. The reason you do not style "" directly is for the same reason mentioned above. You don’t want a new window icon appearing if Javascript isn’t enabled and the link wont spawn a window.

Added bonuses

This simple little approach has some great added bonuses too. Firstly, the providers who create the links in the first place don’t need to add title tags or set the destination window for the link. Secondly, it would be easy to create an additional bit of JavaScript that allows the user to enable or disable window spawning. This gives the control back to the user where it belongs.

So what do you think? Have I missed something? Can this approach be improved? Do you believe you should never spawn a window?

Post to Twitter Post to Delicious

What did you think about this post?

29 Comments

Comments are for the discussion of this post. If you have other questions / comments then post them to the forum or send me an email

  • A very useful and helpful technique which i have been using for quite some time, although i still used the externalLink class to change the css. I think i will edit my code to include what you did, where if javascript is disabled, the user doesn’t see the styling.
    One very small thing that i think could be changed, when you change the title where the title was already empty, it creates a useless space at the beginning of the tag. Just thought maybe you could do a check to see if the title is empty, if it is then don’t display a space. I know it’s a very small thing but it just makes it seem a little bit more professional.

  • Dennis says:

    I’ve been practicing a very similar method, but instead of class=”externalLink”, I use rel=”external”. I believe it’s more semantic.

  • Paul Boag says:

    Hi daniel,
    yeah I am aware of that one. I didnt include it in the demo because I wanted to give people a fighting chance of understanding my code. I have also been too lazy to fix it on my own site :-s

  • Paul Boag says:

    Hi Dennis,
    yes I guess you are right. That would be more semantic. Of course that would make the javascript code sligtly more complex but it is a good idea.

  • Ed says:

    Unfortunately the pages I want to talk about here seem to be offline, so I’ll link to the archive.org versions instead.)
    Just wondering whether you have considered doing what is suggested in task 3 in a Dom Scripting tutorial where the link is determined to be external “by checking that the href attribute does not contain window.location.hostname”. This can be seen in the code of the answer page for the task:
    ////////////////////////////////////////////
    // take the link’s href
    islink=as[i].href;
    // and check if it contains the current location
    if(islink.indexOf(window.location.hostname)==-1)”
    ////////////////////////////////////////////
    One thing to watch out for with doing that is, it makes it harder to test the code on an offline PC – but it means you can reduce the amount of code you produce, as you can get rid of all the “externalLink” classes.

  • Paul Boag says:

    To me that is a hammer to crack a walnut. Also it takes away the designers control over what is defined as an external link which sucks.

  • Ed says:

    Are you saying you would want to apply the “externalLink” class name to something that isn’t an external link, or that you would want to only apply the “externalLink” class to some external links and not others?
    If it is the former, then shouldn’t another name be found for the class, for semantic correctness? If it is the latter, wouldn’t that make it harder for people to get used to the web site’s interface, as they have one reaction to some external links, and another reaction to others.
    Also, could you take another look at the code you are using to make the new windows? It does odd things with Firefox’s tabs: If you hold down the Control key while clicking an external link, you get a new window pop up and the link in a new tab – the link should only appear in a new tab. If you middle-click the link, it only appears in a new tab, which is the correct behaviour.

  • Paul Boag says:

    Hi Ed,
    In regards to your first point: I have no idea what you are talking about!
    As for your second point: do it yourself! :)
    I was demonstrating a principle not providing reusable text. There are a lot of other people out there that do that.

  • Ed says:

    Ok, I’ll try again:
    you said that using the “window.location.hostname” method “takes away the designers control over what is defined as an external link”. Surley an external link is always the same thing: a link to another web site. If the class name “externalLink” was given to anything other than an external link, I don’t think it would be semantically correct. However, if some external links did pop up in a new window, and others didn’t, couldn’t that confuse some users and make the site harder to use?

  • Paul Boag says:

    Okay I understand now. I dont think it is fair to say that the hostname is always an indication of an external site. For example we have had many clients that run subsites within their main site with their own unique domains. These have a different domain but wouldnt in my opinion be classed semantically as an external link. Sure “technically” they are external because they have a different domain, but in the real world their not.

  • Ed says:

    Ok. Fair enough.

  • Gerben says:

    I’d like to add a bit to the code to make it less abtrusive.

    links[i].onclick = function(e) {
    if(!e)e=window.event;
    if(e.shiftKey || e.ctrlKey || e.altKey) return;
    window.open(this.href);
    return false;
    }

    This way people can still open a link in a new tab etc. if the really want to.

  • Thanks for that Gerben, very useful
    Yhink I will use that in my code, if it’s not a problem?

  • Gerben says:

    no problem. I wished more people would write userfriendly/usercentered code.

  • Paul Boag says:

    Here is an updated version of the code including some feedback I have received:
    function doPopups() {
    if (!document.getElementsByTagName) return false;
    var links = document.getElementsByTagName(“a”);
    for (var i=0; i

  • Gerben says:

    one could even use
    links[i].target = ‘_new’;
    instead of links[i].onclick = … if you don’t want to specify any other window-properties for the popup.
    nice idea to add ‘(new window)’ to the title-attr.

  • ptvGuy says:

    Okay, as much as I like this method–and I’ve even been working it into my own blog–I have not been able to figure out a way to exclude linked images from having the same little externalLink icon as the externally linked text. This is very annoying. BTW, there’s also a problem with text hyperlinks that span two or more lines on the page.
    Has anyone figured out a workaround for this yet? I’d really hate to have to create a separate class handler for images (like externalLinkImg) as well as the corresponding JavaScript function to process it without the newWinStyle.

  • Ed says:

    ptvGuy, I guess you could add a bit of javascript to say “if the doesn’t contain an image, don’t add the rest of the code”
    something to do with child nodes, I would think

  • Ed says:

    “if the doesn’t contain an image, don’t add the rest of the code”
    should be
    “if the link doesn’t contain an image, don’t add the rest of the code”

  • Ed says:

    eeeek – I mean
    “if the link contains an image, don’t add the rest of the code”
    I really should slow down!

  • ptvGuy says:

    The way the function is currently written, it uses “getElementsByTagName” to pull out properties of the anchor tag itself. That means that it will process elements of the anchor tag like “title,” “href,” and “class.” It completely ignores whatever’s between the opening and closing anchor tags as to whether it’s text an image or nothing at all. That means that I could potentially apply the externalLink class to an empty named anchor and have it simply make the new window icon appear in a spot with no related hyperlink, have a title text that says “(new window)”, and actually open a new window with nothing in it.
    I’d really hate to add any overhead to what is already a distractingly slow-running script. That’s not a complaint, by the way. It’s just that the JavaScript can’t process the anchor tags until after the page loads. That means that users can actually see the page being changed after it already appears to be loaded. One could even make the argument that this could be confusing to users with cognitive disabilities (or those with little or no computer experience), and I’m not exactly certain how this might affect people using screen readers who may try to access the various hyperlinks before the page has finished processing.
    I realize that we can’t make everything perfect for everyone or cover every potential situation. Most of us (web developers) don’t get paid for or have the time available to do many of things we’d like to do for accessibility. So, for ease of implementation and maintenance, this is the best method I’ve seen yet. It just needs some tweaking and refinement.
    I’ve tried using CSS in different ways to isolate anchor tags with images and prevent the icon from appearing, but it hasn’t worked:
    a.newWinStyle img {
    background-image: none;
    padding: 0;
    }
    img a.newWinStyle {
    background-image: none;
    padding: 0;
    }
    I hope that we can get some discussion going on this subject again and possibly work out this annoying problem along with what to do about multiline text hyperlinks.

  • James Bellew says:

    Hi Paul
    I tried using the re-do of your javascript that you added later on – but it’s got a coding error. I guess it was a cut and paste issue…
    function doPopups() {
    if (!document.getElementsByTagName) return false;
    var links = document.getElementsByTagName(“a”);
    for (var i=0; i
    **** it was missing this bit *****
    < links.length; i++) {
    **** end of extra code *****
    if (links[i].className.match(“externalLink”)) {
    links[i].className = links[i].className + ” newWinStyle”;
    if (links[i].title == “”) {
    links[i].title = “(new window)”;
    }
    else {
    links[i].title = links[i].title + ” (new window)”;
    }
    links[i].onclick = function(e) {
    if(!e)e=window.event;
    if(e.shiftKey || e.ctrlKey || e.altKey) return;
    window.open(this.href);
    return false;
    }
    }
    }
    }
    See ya.

  • nxtyear says:

    ok i’m relatively new so i might need help here,
    which class do i style in CSS?
    i tried styling the .newWinStyle but it doesn’t seem to work.
    could someone please explain what this line is doing?
    links[i].className = links[i].className + ” newWinStyle”;

  • nxtyear says:

    ok.. just found out the whole script isn’t working, not just the style.
    none of the links with the class “externalLink” is opening it in a new window…
    is there any reason why it might be that i’m the only one having trouble getting it working :S?
    mind you i’m including an external js file into a phpinclude. which in turn is applied to the page with the links.. would that have anything to do with this?

  • ptvGuy says:

    nxtyear:
    Without a link to your site, no one can look at what’s going wrong. I would suggest opening the page in your favorite browser and then viewing the source code to see if the JavaScript coding is even getting to your page correctly from the PHP include. Then look through your external link anchors in that source code to see if they’re properly coded with the the class=”externalLink” attribute. Doublecheck the class designation as well to make sure that it’s all lowercase except the capital “L” since JavaScript is case-sensitive.
    BTW, I apologize if that information is just painfully obvious to you, but I have no way of knowing your coding level, and I wanted offer as much input as I could. I hope that helps.

  • nxtyear says:

    actually, i figured out the problem, it seems that browsers don’t support “getElementsByTagName” yet. i’ve no idea how paul got it working though :S

  • Acronyms says:

    I would highly appreciate if someone give me a clue on icons in the end of multiline links.

  • wow gold says:

    would highly appreciate if someone give me a clue on icons in the end of multiline links.

  • 彼女 says:

    nice site. thanks.

Leave a comment

Additional Information

Produced by Headscape

Boagworld is produced by the web design agency Headscape founded by Marcus, Paul and Chris Scott. Headscape also has a number of other talented guys who blog. Check them out.

  • Craig Rowe is one of our amazing developers and writes some superb posts on everything from .net to AIR apps.

  • Ed Merritt is a Headscape designer who's blog contains examples of his work and a number of free Wordpress themes.

  • Dave McDermid is a Headscape developer who has an excellent blog. He blogs on everything from AJAX to security.

  • Rob Borley is one of our project managers and blogs regularly on client and project management issues.

  • Leigh Howells is our multimedia design guru (whatever one of those is). He blogs on a mixture of design and music.

You can now download my video presentation of 40 better ways to work with clients for only £9.25.