Skip to the Main Content

Note:These pages make extensive use of the latest XHTML and CSS Standards. They ought to look great in any standards-compliant modern browser. Unfortunately, they will probably look horrible in older browsers, like Netscape 4.x and IE 4.x. Moreover, many posts use MathML, which is, currently only supported in Mozilla. My best suggestion (and you will thank me when surfing an ever-increasing number of sites on the web which have been crafted to use the new standards) is to upgrade to the latest version of your browser. If that's not possible, consider moving to the Standards-compliant and open-source Mozilla browser.

October 24, 2004

Accessible Popups

It’s been a while since I did a post about Web-Design, so here goes.

First, a disclaimer: while I am a proud owner of Joe Clark’s book (one of the two books on Web-Design that I own), that hardly qualifies me an expert on accessibility; you will probably find better advice from more knowledgeable sources elsewhere.

Anyway, for a variety of reason, including the fact that this precipitously cuts down on comment spam, the comment entry form is absent from the individual archive pages of this blog. Rather, it’s on its own dynamically-generated page and you need to follow a link to get to it. And, for reasons both æsthetic and practical, I decided that the comment-entry page should appear in a popup window1. The code I started with looked like this

<a href="..."
onclick="OpenComments(this.href); return false;"
title="Respond to comment by ...">Reply to this</a>

The OpenComments() function creates the popup window. This code degrades gracefully. If the user has Javascript disabled, following the link opens the comment-entry page in the current window.

That’s good, but it could be better. The onclick event handler only applies if the user is navigating with a mouse (or similar pointing device). What about users who, perhaps because of a disability, are using the keyboard (or similar device) for navigation? We can accommodate them, too, by adding an onkeypress event handler2

<a href="..."
onclick="OpenComments(this.href); return false;"
onkeypress="OpenComments(this.href); return false;"
title="Respond to comment by ...">Reply to this</a>

I’ve been using this code for a year and a half, with nary a complaint, but it does conceal a serious usability gotcha3.

Consider the following steps

  1. Click on a “Reply to this” link, opening a comment-entry popup window.
  2. Start filling out the comment-entry form.
  3. Click on the main window, to bring it to the front.
  4. Hit any key.

Since the “Reply to this” link in the main window still had focus, the onkeypress event handler interprets your hitting a key to be a request to reopen the comment-entry popup window. Poof! There goes the comment you were composing.

Oops!

I was certainly aware of the problem but, since none of my commenters ever complained, I never got around to thinking about how to fix it. Perhaps my commenters were too shy to point out the problem or perhaps it simply hasn’t affected them.

One of the endearing features of Luboš Motl is that he is not shy about such matters. When he encountered the bug, he promptly declared my comment system “unusable.” And that, finally, got me off my duff to fix it.

The fix is simple: make sure that, after creating the popup, you drop focus on the link

<a href="..."
onclick="OpenComments(this.href); this.blur(); return false;"
onkeypress="OpenComments(this.href); this.blur(); return false;"
title="Respond to comment by ...">Reply to this</a>

I’m gonna guess that this is almost alway the right thing to do when you use an onkeypress event handler. Not dropping focus will frequently lead to unexpected results.

Another Usability Glitch Remedied

While we’re on the subject of comment popups, there’s another usability issue with MovableType’s comment popups. They are all named “comments

function OpenComments (c) {
    window.open(c,
                    'comments',
                    'width=480,height=480,scrollbars=yes,status=yes');
}

So, you pop open a comment-entry window, start typing a comment, switch to another window, surf for a bit, absent-mindedly click on a comment link, … and wipe out the comment you had been composing.

Oops!

Since MT doesn’t actually use the name to do any fancy window manipulation, let’s make the name unique

function OpenComments (c) {
    window.open(c,
                    Math.round(Math.random()*10000),
                    'width=600,height=480,scrollbars=yes,resizable=yes,status=yes');
}

Now our comment-entry windows won’t stomp on anyone elses, or vice-versa.


1 I know there are some who insist that you must never popup a window, unbidden by the user. This post is not for them. It is a long-established convention, both on the Web and in GUI computer applications generally, that user input is solicited in a popup window or dialog box. I’m just following that convention. The “Don’t break the ‘Back’ button” mantra is of little relevance. In the midst of filling out the form, most users are afraid of hitting the ‘Back’ button, for fear of losing all their work.

To be on the safe side, however, I alway indicate that a link will open in a new (popup) window, by displaying a distinct cursor when you hover over the link.

2 There are “non-device-specific” event handlers which one could try to use in this context. But I could never get them to behave satisfactorily. Perhaps it’s the state of current browser support. In any case, onclick="..." onkeypress="..." covers just about any input device likely to be in use.

3 There are also accessibility problems with this technique, as presented here. Fortunately, those, too, are easily fixed.

Posted by distler at October 24, 2004 1:10 AM

TrackBack URL for this Entry:   http://golem.ph.utexas.edu/cgi-bin/MT-3.0/dxy-tb.fcgi/459

6 Comments & 0 Trackbacks

Re: Accessible Popups

I use pretty much the same method on my website. Same goes for the pages where I have to display a gallery of images. The only issue that I still have is that if I Option/Ctrl-click click in Firefox I get both the pop-up and the page opening in a new tab. Since it’s easier to close a window than a tab I imagine that most users will not look at the page in the pop-up, as it’s designed for. Any ideas?

Posted by: quis on November 3, 2004 5:09 PM | Permalink | Reply to this

Re: Accessible Popups

How about changing the href attribute with JavaScript? Lets say, first we have this:

<a href="/cgi-bin/MT-3.0/sxp-comments.pl?entry_id=459">Post a New Comment</a>

And with some DOM scripting, we change it into:

<a href="javascript:OpenComments(this.href); return false;">Post a New Comment</a>

That would probably be device independant, accessible and get rid of the problems onkeypress brings. :)

Posted by: zcorpan on December 29, 2004 6:30 PM | Permalink | Reply to this

Javascript href’s

Device-independent, but fails spectacularly if Javascript is disabled. The event-handler way of doing things degrades gracefully if you disable Javascript. On the other hand, it requires a bit more care-and-feeding.

Posted by: Jacques Distler on December 29, 2004 9:35 PM | Permalink | PGP Sig | Reply to this

Re: Javascript href’s

When JavaScript is disabled, the href will still be /cgi-bin/MT-3.0/sxp-comments.pl?entry_id=459… Right?

Posted by: zcorpan on December 31, 2004 8:01 PM | Permalink | Reply to this

Re: Javascript href’s

Oh. I see.

I misunderstood your suggestion. Yes, something like that ought to work.

I worry about the reputedly dodgy support for attribute manipulations in the DOM scripting implementations of some browsers.
It would be nice to see that a full-fledged version of your idea works in practice in major browsers.

Posted by: Jacques Distler on January 1, 2005 11:15 AM | Permalink | PGP Sig | Reply to this

Example script

I found this article and made some minor changes to make it manipulate the href instead of adding target="_blank"… Here’s what I got:

function popupLinks() {
 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") == "popup") {
     anchor.href = "javascript:popup();";
     anchor.className = "popup";
  }
 }
}
window.onload = popupLinks;

function popup() {
 void(window.open("http://w3.org/","","width=310,height=150,resizable=yes,status=yes"));
}

And the links could look like:


<a rel="popup" href="http://w3.org/">W3C</a>

It works in IE6 (in quirks mode aswell) so I think we have covered most major browsers… Especially since Mozilla, Opera and Safari has no problem with DOM scripting. :)

Posted by: zcorpan on January 3, 2005 9:02 AM | Permalink | Reply to this

Post a New Comment