The Perfect Pop-up (Updated 20 March 2007)
This is an update of the article that was originally posted in November 2002]. This update demonstrates methods that use unobtrusive JavaScript and CSS to trigger the pop-up, and all references to inline event handlers have been removed.
Posted on: 20 March 2007.
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 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 many browsers, the default option is now 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?
Start with a Basic Link
The first thing to do is to assume that your pop-up will not work. With so many possible reasons for this, you would be unwise to think anything else. So, just use the right markup for the job - you need to link to something, so just create a link:
<a href="file.htm">Here is my link</a>
But you want the people who can use pop-ups to get that effect right? So how do you identify that this link is going to generate a pop-up window for those who can get it? You have a few choices, but I'm going to suggest that you use the rel
attribute. You could simply use a class
attribute and attach the JavaScript behaviours to that, but I'm going to suggest that you use the rel
attribute and within that you can stack up a number of alternative attributes that will affect the way the link appears/behaves. In effect, you'll use the class
attribute as a hook from which we can hang the visual style (CSS) and rel
for the behaviour (JavaScript). Here's a very basic example of the markup required:
<a href="file.htm" rel="popup">Here is my link</a>
Seeking out the Pop-ups
So
you've got a simple link, given it a rel
of popup
- now it's time for the JavaScript to kick in and add in the behaviour. As is the way of doing things these days, we'll be using some nice unobtrusive JavaScript to achieve this - that's to say no inline event handlers (e.g. a onclick="foo()"
) and so on but instead it all goes into an external .js file. For this to work, we'll also require an addevent function (addevent.js).
The JavaScript starts working immediately after page load by calling a function that trawls through the page seeking out all a
elements that have the rel
attribute of popup
:
addEvent(window, 'load', findPopUps, false);
In the findPopUps
function, if the correct rel
attribute is found, the script attaches a behaviour (which we'll see defined shortly) and also applies some background/padding effects to visually indicate that this is a pop-up; in addition, it automatically appends a title
attribute to signify that it is a pop-up.
function findPopUps() { var popups = document.getElementsByTagName("a"); for (i=0;i<popups.length;i++) { if (popups[i].rel.indexOf("popup")!=-1) { // attach popup behaviour popups[i].onclick = doPopUp; // add popup indicator if (popups[i].rel.indexOf("noicon")==-1) //more of the 'no icon' thing in a moment ... { popups[i].style.backgroundImage = "url(pop-up.gif)"; popups[i].style.backgroundPosition = "0 center"; popups[i].style.backgroundRepeat = "no-repeat"; popups[i].style.paddingLeft = "15px"; } // add info to title attribute to alert fact that it's a pop-up window popups[i].title = popups[i].title + " [Opens in pop-up window]"; } } }
You may be wondering why the styles are applied using popups[i].style
rather than applying a class
- this is just to avoid overriding an existing class
that may be present (you could adapt the script such that classes are strung together rather than replaced, however).
So we've found the pop-ups, given them a visual lick to make it clear that they are pop-ups and have attached the behaviour. But what is this behaviour?
Adding the Pop-up Behaviour
We just saw how the pop-up links are identified and then given a function to run when activated (by click or press):
popups[i].onclick = doPopUp;
So, what exactly does doPopUp
do? Well, it let's you specifiy a few parameters about the pop-up window, for starters.
At its very basic level, all you need to do is state that the link is a popup by using rel="popup"
. However, in reality, you'll probably want to affect the appearance of it a bit more than that, for example setting the:
- height
- width
- presence of toolbars
The usual kind of stuff. Thankfully, the script can accept such optional attributes:
rel="popup type width height noicon"
... but they must be in that order (and without any ommissions from the middle) . If none are specified, the script can use some defaults, which you could obviously set according to your audience.
[The noicon
attribute is there to avoid some unsightly effects that may occur in certain circumstances. For example, while it might be good to have the pop-up indicator showing for links in the body of the page, should you need to add a pop-up link elsewhere, like a navigation bar for example, it may be a bit jarring; the noicon
attribute lets you override the script's default behaviour for styling pop-up links.]
Here's the function in full:
function doPopUp(e) { //set defaults - if nothing in rel attrib, these will be used var t = "standard"; var w = "780"; var h = "580"; //look for parameters attribs = this.rel.split(" "); if (attribs[1]!=null) {t = attribs[1];} if (attribs[2]!=null) {w = attribs[2];} if (attribs[3]!=null) {h = attribs[3];} //call the popup script popUpWin(this.href,t,w,h); //cancel the default link action if pop-up activated if (window.event) { window.event.returnValue = false; window.event.cancelBubble = true; } else if (e) { e.stopPropagation(); e.preventDefault(); } }
Note that there is one last thing going on here - this function calls one last function called popUpWin
. This should be much more familiar territory,
as it takes the values passed in to create the typical pop-up window.open
method:
function popUpWin(url, type, strWidth, strHeight){ closeWin(); //calls function to close pop-up if already open, //to ensure it's re-opened every time, retainining focus type = type.toLowerCase(); if (type == "fullscreen"){ strWidth = screen.availWidth; strHeight = screen.availHeight; } var tools=""; if (type == "standard") tools = "resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes, width="+strWidth+",height="+strHeight+",top=0,left=0"; if (type == "console" || type == "fullscreen") tools = "resizable,toolbar=no, location=no,scrollbars=no,width="+strWidth+",height="+strHeight+",left=0,top=0"; newWindow = window.open(url, 'newWin', tools); newWindow.focus(); }
Some example pop-up links
So, stringing it altogether, here are some examples using the different parameters available in the rel
attribute. You can see the visual effect of the pop-up image being added to these links (except for the one wher the noicon
attribute has been applied)
- A normal link -
<a href="http://lloydi.com/blog/">
- A popup link (just requires class of popup in link) -
<a href="http://lloydi.com/blog/" rel="popup">
- A popup in standard mode (toolbars included) -
<a href="http://lloydi.com/blog/" rel="popup standard 800 600">
- A popup in console mode (no toolbars etc) -
<a href="http://lloydi.com/blog/" rel="popup console 800 600">
- A popup link for fullscreen -
<a href="http://lloydi.com/blog/" rel="popup fullScreen">
- A popup in standard mode (icon suppressed) -
<a href="http://lloydi.com/blog/" rel="popup standard 800 600 noicon">
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:
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 page did not load in a new window. The 'close this window' link that you so thoughtfully provided will prompt a not very friendly dialogue like this:
Or at least it will for IE6 users - other browsers may have variations on this theme. 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)
The final perfect pop-up script
The complete scripts for this technique can be copied from the files linked to below (right-click and choose 'Save Link As', or whatever your browser of choice words it as):
You'll need to link to these files in the head
of your document like so:
<script type="text/javascript" src="/path-to/add-event.js"></script>
<script type="text/javascript" src="/path-to/popup.js"></script>
The syntax for creating the links in your markup is as shown in the previous section. But we can do one better than that:
- Use the updated pop-up window generator and save time fussing about trying to remember what order the attributes need to be :-)
Conclusion
Hopefully this tutorial has demonstrated that pop-up links can be accessible, search-engine friendly and non-invasive. With browser support for these scripting techniques being so good, you should find the technique works well in almost every modern browser you try it on - and for those that don't carry out the script, you're still left with a basic link to follow, so nobody has to miss out. However, even if you follow all of this advice you should still ask yourself if you really need to open a new window.
Remember:you can use the Pop-up Window Generator, which uses the script detailed in this article.
Tutorial written by Ian Lloyd.