Popups

See section 6B of the book.

Sometimes it's useful to add a popup to your pages. When the user clicks on a link, a new window opens and displays a page.

There are two ways to do this. You can add a TARGET="_blank" to the <a>-tag, but this simply opens a new browser window that completely obscures the old one.

This may be what you want, but at other times a small window on top of the large browser window is much better. This small window is popularly known as a popup.

First the basic syntax of how to create a popup, then an explanation of the script, including a table of the most common arguments you can give to a popup and the problem of focusing.
Then a new way of adding popup behaviour to a link. This site uses the new system because it's much cleaner than the old one.
Finally some notes about writing content directly into the popup. This gives several problems, most importantly the confusion over exactly what the URL of the popup is.

Creating a popup

To create a popup you'll need the following script:

<script language="javascript" type="text/javascript">
<!--
function popitup(url) {
	newwindow=window.open(url,'name','height=200,width=150');
	if (window.focus) {newwindow.focus()}
	return false;
}

// -->
</script>

Then, you link to it by:

<a href="popupex.html" onclick="return popitup('popupex.html')"
	>Link to popup</a>

Open popup.

See below for a far cleaner way of adding popup behaviour to a link.

Explanation

First, you open the new window. The page to be opened is passed on by the argument url. Note that, if you want to open a page on another server, Explorer will frequently give errors. This is a feature, not a bug, so there's little you can do about it.

You have to give a name to the window (in this case, name). This name can be used as the target of a link.

In addition, you have to load the window into a JavaScript variable. The reasons for this are complex and have mostly to do with preventing errors in various browsers, especially when you want more links to lead to the same popup.

function popitup(url) {
	newwindow=window.open(url,'name','height=200,width=150');

Arguments

So first we define the url to be loaded in the popup and then the useless name.

As third argument, you can assign all kinds of variables. Most common are height and width, which define the height and width of the new window.

'height=200,width=150'

As soon as you define anything, all yes | no arguments that you have not defined are set to no.
Warning: Spaces or hard returns are not allowed within the quote-marks.

Open popup, and set the arguments through the checkboxes below.

dependent
directories
fullscreen
location
menubar
resizable
scrollbars
status
toolbar
top=200
left=400
width=200
height=200
screenX=400
screenY=200

Multiple IE problem: if IE5.5 is open, IE6 and 7 may crash on this test. Unfortunately the crash is not totally reproducible.

Method or property IE 5.5 IE 6 IE 7 FF 2 FF 3b3 Safari 3.0 Win Opera 9.5b Konqueror 3.5.7
dependent
Makes the popup dependent on the main window
No No No No No

If a popup is dependent on the main window it doesn't show up in the list of windows. No browser seems to support this any more. Opera doesn't show any popup in the list of windows, whether you set dependent or not.

fullscreen
Should the popup be fullscreen?
Yes Incomplete No No No Yes
IE7 shows the window bar and URL bar. That's actually a good idea, but when interpreting the results strictly it's a slight bug.
height
Height of the popup in pixels
Yes Yes Yes Yes Yes
Without a height browsers give the popup the height of the spawning window. Exception is Opera, which creates a new window-tab if either width or height is undefined.
left
left coordinate of the popup in pixels
Yes Yes Yes Yes Yes
Without a left the popup is placed about 20px right of the upper left corner of the spawning window.
location
Should the location bar be shown?
Yes Buggy Yes No Yes
The location bar is where the URL of the current page is shown. Mozilla shows the location bar, but it's not user-editable.
menubar
Should the menubar be shown?
Yes Yes No No Yes
The menubar contains File, Edit, etc. Of course it's impossible to hide the menubar on Mac.
Method or property IE 5.5 IE 6 IE 7 FF 2 FF 3b3 Safari 3.0 Win Opera 9.5b Konqueror 3.5.7
resizable
Is the popup resizable?
Yes Not necessary Buggy Not necessary Not necessary
The popup is always resizable in Mozilla, Opera and Konqueror. When making the popup resizable in Safari, actually resizing it makes the popup jump to a width of ca. 400px, which cannot be decreased.
screenX/Y
Location of the popup, in pixels
No Yes Yes No Yes
 
scrollbars
Should the popup have scrollbars if it needs them?
Yes Yes Not necessary Yes Yes
The popup automatically gets scrollbars in Safari, even if this property is set to No.
status
Should the status bar be shown?
Yes Not necessary Yes No Yes
Mozilla always shows the status bar.
toolbar
Should the toolbar be shown?
Yes Yes Yes No Yes
The toolbar contains the Back, Forward, etc. buttons.
top
top coordinate of the popup in pixels
Yes Yes Yes Yes Yes
Without a top the popup is placed about 20px below the upper left corner of the spawning window. Exception: Konqueror places it flush with the bottom of the screen.
width
width of the popup in pixels
Yes Yes Yes Yes Yes
Without a width browsers give the popup the width of the spawning window. Exception is Opera, which creates a new window-tab if either width or height is undefined.
Method or property IE 5.5 IE 6 IE 7 FF 2 FF 3b3 Safari 3.0 Win Opera 9.5b Konqueror 3.5.7

Focus

Then we place the focus on the new window so that it's on top of the main window. First check if the browser supports the focus() method, if so place the focus on the new window.

	if (window.focus) {newwindow.focus()}

Accessibility

Finally we return false. This is to prevent the browser from following the actual link.

	return false;
}

When calling the script, make sure you do this:

<a href="popupex.html" onclick="return popitup('popupex.html')"
	>Link to popup</a>

The normal link leads to the page you want to show, while the popup script is called in the onclick event handler. When the script is called, it returns false to prevent the browser from following the link.

The trick is that when JavaScript is disabled and the popup script doesn't work, the link simply leads to the page. Thus your popups remain perfectly accessible.

Custom attributes

When I created QuirksMode.org I became heartily sick and tired of the ugliness of the HTML of popup links. Therefore I invented a new system. I declare popup links as follows:

<p>See also the <a href="../key.html" type="popup"
	>key</a> to my compatibility tables.</p>

Note the custom type="popup" attribute. Each time you load a new page, an onload script is executed. One of the things it does is:

var x = document.getElementsByTagName('a');
for (var i=0;i<x.length;i++) {
	if (x[i].getAttribute('type') == 'popup') {
		x[i].onclick = function () {
			return pop(this.href)
		}
		x[i].title += ' (Popup)';
	}
}

I go through all links on the page and check for this attribute. If the script finds it, it adds an onclick event handler:

		x[i].onclick = function () {
			return pop(this.href)
		}

The event handler calls the function pop() (which is almost the same as the test function popitup() I use on this page). It passes this.href as an argument, which is the actual href of the link the user clicked on. pop() returns false for the accessibility reasons I described above, and the event handler returns it to the event, so that the actual link is not followed.

Simple and clean, works in all browsers. The only slight disadvantage is that no current XHTML specification allows the use of custom attributes. Personally I don't care, but if you wish to write flawless XHTML you cannot use this technique.

Writing into popups

Writing the content directly into the popup does not work in Explorer 3 on Windows, Konqueror 2.2.2 and Omniweb.

As you've seen above, you can load a new page into the popup. However it's also possible to write the content into the popup by means of JavaScript. This has the advantage that you don't need to write an entirely new page for display in the popup, but it also has disadvantages.

First of all, try it.

This is done as follows:

function popitup2() {
	newwindow2=window.open('','name','height=200,width=150');
	var tmp = newwindow2.document;
	tmp.write('<html><head><title>popup</title>');
	tmp.write('<link rel="stylesheet" href="js.css">');
	tmp.write('</head><body><p>this is once again a popup.</p>');
	tmp.write('<p><a href="javascript:alert(self.location.href)">view location</a>.</p>');
	tmp.write('<p><a href="javascript:self.close()">close</a> the popup.</p>');
	tmp.write('</body></html>');
	tmp.close();
}

As you see, open the window, write the HTML into newwindow2.document and it works. The document.close() at the end is something different than a window.close(), it kind of means that the document inside the popup is closed for writing. I found out this statement is necessary in Netscape 2, 3 and 4 to see anything at all and in Opera 5 when you want to open the popup more than once. Without the statement you can open it only once, the next time you click on the link nothing happens.

Explorer 4 on Windows

Explorer 4 on Windows is a problematical browser. First it steadfastly refused to execute the script above, even when I changed every document.write to a document.writeln on the advice of a reader. Then when I restarted my computer, Explorer 4 always executed the script correctly, whatever the exact code. At the moment I'm not sure if it supports this way of writing to a popup or not. It seems to work.

So I do not guarantee Explorer 4 compatibility, but the script will probably work.

The URL of the popup

Opera 3 and Hotjava 3 give 'blank' as the URL of the popup, while Opera 5 on Mac thinks it is ~i.

Opera 5.11- on Windows and Linux crash on the View Location link.

There's one catch however: what exactly is the URL of the page in the popup? As you might have expected, different browsers have different opinions. I put a link 'View location' in the popup that displays the location.href of the page. Usually the location is this page, popup.html, that's because the browser sees the popup as a kind of extended part of this page.

I noticed this problem because a colleague of mine wanted to use this sort of script for making a printer friendly version of a page. Write the content into a popup, with minimal markup, and then let the user press 'Print'. Unfortunately most browsers printed out the main page because they executed the print() command for the location.href (the main page), which was not at all what he had in mind.

Interestingly, the self.close() command always correctly closes the popup, not the main page.