The Perfect Pop-up

Posted on: 20 November 2002

If you believe the likes of Jakob Neilsen and his supporters, nothing is more evil than pop-up windows. And in many ways, this is correct. Why? Well, we'll list the reasons soon enough, but in a nutshell it's because they are nearly always poorly implemented or simply not needed. This tutorial will show that, with the right thought, pop-up windows can be used without upsetting anyone - particularly the person browsing your site.

Problems with pop-ups

The common faults with pop-up windows are:

  • If scripting is disabled, or if the browser does not support JavaScript, the pop-up will not work
  • Search engines cannot follow links to pop-up windows (scripted elements are always ignored)
  • Pop-ups present accessibility problems
  • Site management tools (e.g. DreamWeaver) cannot update links to pop-ups if you move the destination page to another section of your site
  • Many people have pop-up killers running that close the window the moment they are opened
  • In Mozilla, there is an option to stop pop-ups opening in the first place

Phew. That's quite a list ... and you could probably add your own to this list. So, how do we address these?

Scripting disabled

With scripting disabled, the pop-up does nothing. Simple as that. But if you used a standard <a href>, there would be no such problem. So, instead of using

<a href="#" onclick="window.open('file.htm');">

you might use

<a href="file.htm" onclick="window.open('file.htm');return false;">

This way, if scripting is disabled, the standard link still works.

However, perhaps there is a very good reason why you want the window to open on top of the current window. So, you add a target attribute like so:

<a href="file.htm" onclick="window.open('file.htm');return false;" target="newWin">

Bingo. Problem solved. Or is it? It turns out that in XHTML strict, the target attribute has been dropped - this is a problem, but there is a way around it, and this is covered later. For the moment, we'll assume HTML4.01 or XHTML transitional is acceptable. But there's more we can do to improve this window opener.

Search engines

With the amended code above, search engines get a standard href to follow, so that's that issue ticked off our problems list.

Accessibility problems

The biggest fault with pop-ups is that it takes the focus away from the main browser window, and this can be disconcerting. It presents general usability issues aside from accessibility. How often have you seen someone launch a pop-up and then inadvertently click back on the launcher window and thinking that nothing's happened, click the link again with nothing happening? Of course the window has opened but is now under the launcher window, and only moving down to the task-bar and selecting the window from there will solve this.

The trick is to inform the user that it will open in a new window and there are a number of ways to address this:

  • Include instructions as part of the link itself
  • Add some instruction in a title attribute
  • Use an appropriate icon to signify a pop-up is imminent

This way, if focus is lost, the user may make the connection, e.g.

Open my test page (opens in a pop-up window)

This link loads a pop-up windowOpen my test page

To address the issue of a window losing focus, you can use JavaScript to re-set the focus. A proposed script for this appears at the end of this document, you lucky people!

Site link management tools

If you are in the habit of moving pages around using tools like DreamWeaver or a content management system, you would hope that links are maintained. With standard hrefs, they usually are (depending on the tool you use), but with JavaScript it's unlikely. Returning to our code for a moment then:

<a href="file.htm" onclick="window.open('file.htm');return false;">

The link above would be maintained quite nicely ... almost. Half of it would - the href part. The onclick part would probably be ignored. This is a big problem. You might think that your links have been updated, but in fact for people who do have JavaScript enabled, they would be sent to a missing page. So, you might find your code would be changed to:

<a href="newlocation/newfile.htm" onclick="window.open('file.htm');return false;">

And if you were to run a link validator on the launcher page, it would appear that your link is indeed valid. So, how do we address this issue? Like so:

<a href="file.htm" onclick="window.open(this.href);return false;" target="newWin">

Only one link to maintain, and the correct href will be used for the window.open method. Excellent - we're getting somewhere!

Pop-up killers/Mozilla disable pop-ups

As with the issue of JavaScript being disabled, merely providing a standard href means that the link will still work Now we only have to address the issue of which window has focus ...

The final perfect pop-up script

We recommend using a function which can be placed in some commonly shared JavaScript code (as we have done with this site) which can easily be called from anywhere in the site. This is far more preferable than laboriously writing the window.open function out each time. In addition to the URL, you might want to include parameters such as height and width and what type of pop-up style to choose (and it's up to you what styles you define). So, in your function you would have:

To call the function you would use the following code:

<a href="my-pop-up-window.htm" onclick="popUp(this.href,'console',400,200);return false;" target="newWin">This is my link</a>

Or, to use some actual examples:

This is my pop-up link (console mode)
This is my pop-up (fixed mode)
This is my (elastic mode)

Note: The 'return false' part effectively cancels out the default action of the href, so won't get the pop-up and a normal HTML window opening - it will be one or the other. Try the links above with and without JavaScript enabled to see for yourself. The additional code in the function handles the focus aspect. If you click on one of the links, then click back on this page such that the pop-up is hidden, then click on another pop-up link, the code assesses the state of the pop-up, then closes the pop-up window and re-opens it with its new dimensions. What more could you ask for? Well there is one final piece of icing on this cake.

Closing the pop-up

Once the pop-up is opened, we might rely on people to use the browser/operating sytem controls to close the newly opened window:

Window controls - minimise, maximise, close

But people don't always do this! So we should provide a link (or button, if you prefer) in the pop-up window itself to close it. However, let's assume that our user has scripting disabled, and that the pop-up window was opened by the standard href route. The 'close this window' link that you so thoughtfully provided will prompt a not very friendly dialogue like this:

Windows dialogue: reads 'Do you want to close this window? [yes] [no]'

To get around this problem, you should write the close link to the web page using JavaScript, and check to see if the window was opened as part of a window.open() method. That way, if it is a true pop-up, the link appears and the close() method will work; if it is not a true pop-up window, the link does not appear. Try the link again, and see for yourself:

This is my pop-up (fixed mode)

XHTML Strict - Dude, Where's my Target?

In XHTML Strict, the target attribute is not supported. Now, assuming that JavaScript is disabled, you cannot force a window to pop-up by using target="_blank" or something similar. In XHTML Strict, you need to use the rel attribute, like so:

<a href="file.htm" onclick="window.open(this.href);return false;" rel="external">

On SitePoint Kevin Yank offers a workaround that describes how to make a correctly marked up link like this behave as it would if you used target="_blank". In his solution, a script runs after the page has loaded and finds all links with a rel attribute of external and then applies a target attribute to them.

function externalLinks() {
	if (!document.getElementsByTagName) return;
	var anchors = document.getElementsByTagName("a");
	for (var i=0; i<anchors.length; i++) {
		var anchor = anchors[i];
		if (anchor.getAttribute("href") &&
		anchor.getAttribute("rel") == "external")
		anchor.target = "_blank";
	}
}
window.onload = externalLinks;

This is all well and good, but think for a moment. If JavaScript is disabled, your pop-up link doesn't behave as a pop-up, there is no target attribute for the browser to fall back on and a script such as that devised by Kevin will never run anyway to counter that.

End result - under XHTML strict, you cannot absolutely force a link to open in a new window - you just have to hope that they not disabled JavaScript or switched on a pop-up killer. Personally, I think this is not a step forward. Others will argue that it is a great step forward if it (coding to XHTML Strict standards) stops people from spawning new windows like a bad case of acne. However, it's not the gun that kills innocent victims - it is the person who pulls the trigger that is responsible. In the right hands, a pop-up can be a friendly beast, but XHTML Strict is having none of it!

Conclusion

Hopefully this tutorial has demonstrated that pop-up links can be accessible, search-engine friendly and non-invasive. However, even if you follow all of this advice you should still ask yourself if you really need to open a new window.

One final point to make is that pop-ups should be something that people opt-in to use, so don't use a window.onload or window.onunload event to force your pop-up window on the user. That always annoys the heck out of people. Unless they wanted to buy an X10 camera or visit the 'World's Largest Online Casino' but didn't know it yet, that is!

Note: If you like what you read here, you'll love this - now on Accessify, the Pop-up Window Generator, which uses the script detailed in this article.

Tutorial written by Ian Lloyd. Portions of this code were provided by Nathan Jones and Chris Whitlock.