
I’ve updated my code with a newer version:
Version 1.2 which includes such awesome things as full IFrame support and better support for classes and styles! You can check out the
Article, or just
download the code from here!
The way the code is used has been changed, so be sure to read the README!
This article will teach you how to:
Open facebook-styled modal windows in both alert box and full ajax-styled version, using the FaceBox modal window script and Prototype.
I wanted my signup page for Ippatsu, an online Japanese learning application, to use a modal window for the sign up dialog. This allows me to use most of the visible area for copywriting, while not requiring a page transition to load the signup form.
You can also create modal windows like these with Prototype and the OSS code I’m releasing below.

Ippatsu's Flashcard FaceBox
A little history
Originally these modal boxes were used mainly for photogalleries and whatnot, and took up the entire screen with a cool faded out background and had a lot of animations. Probably the nicest and most well known was PhatFusion’s lightbox and multibox which are written on the MooTools javascript library.
As time went on, people wanted simpler boxes that did away with all the animation and crap and so extremely simple boxes like Particletree’s Lightbox Gone Wild which is a simple box with no animation over a 70% black border. It’s small, simple and gives a rather nice effect.
So what’s the problem?
Well, the problem with animation should be obvious: It’s slow and can be jerky on certain browsers. Definately not something you want to use for a UI Element.
And the issue with the background is that when you have your entire site blacked out, while you gain focus on the window you’ve just put up, it’s not very useful for information that you want to give the user without preventing them from seeing the rest of your site. In other words, we want a Modal Window instead of a lightbox type thing.
So Bring on the Modal Windows!
As far as this discussion is concerned, I’m going to be ignoring the windows-like full modal windows that allow dragging and dropping and whatnot, and only focus on simple Modal Boxes that can be used to display data. In particular, FaceBox.
Get to the Code Already
Ok, so FaceBox is a JQuery based modal window that is pretty much copied from the facebook site where they use it to display small bits of ajax text. It is amazing. You can get it at http://famspam.com/facebox . However, it only works with JQuery, whose existance I was not aware of at the time of creating my site, so I had to find a Prototype version.
FaceBox Prototype in google gave me a couple of good links, the most popular being Phill Burrows’ blog in which he ported FaceBox from JQuery to Prototype. Unfortunately, the post (and code) is rather old, and did not work on the newest version of Prototype that I was using (1.6.0.3).
Eventually I came to two guys who took Phill Burrow’s code and updated it: Robert Gaal and Scott Davis. Both seem very nice, but I was having some problems with the slightly older Robert Gaal version, and so decided to go with JetViper’s version, as it also proposed to have class support.
Unfortunately there were a few large problems with the FaceBox code as it as written:
- The code did not support class definitions of the FaceBox like it purported to (because of a coding error)
- There was no way to set the size of the FaceBox from code
- If the page being loaded was really long (such as having cakephp debug information) the window would stretch to fit all the contents height-wise, without scrolling
- No iframe support, so loading a page with javascript borked the load.
- No Close on Escape button
So I dug into the code and made some changes, and was able to fix problems 1-3 and 5 (and am still working on 4). The entirety of the code can be downloaded at the bottom of this page.
Fixing the classes
Looking at the original .js (line 175), you can see that Scott’s code says that you can add a class to the FaceBox content by changing the rel tag in the link to “facebox[.my_class]”
// support for rel="facebox[.inline_popup]" syntax, to add a class
var klass = elem.rel.match(/facebox\[\.(\w+)\]/);
if (klass) klass = klass[1];
Unfortunately, due to the way that FaceBox searches for FaceBox-enabled links, it will not recognize “facebox[.my_class]” as a FaceBox, as it looks for a direct match with rel=facebox.
So, I fixed that bug by changing line 93 in the watchClickEvents from
$$('a[rel=facebox]').each .....
to
$$('a[rel|=facebox]').each .....
The |= selector is a CSS Selector (valid in prototype) that allows you to define that The attribute’s exact value is “facebox” or starts with the word “facebox” and is immediately followed by “-”, so it would be “facebox-”. You can read more about Attribute Selectors at Smashing Magazine’s Taming Advanced CSS Selectors. It’s an amazing read. You can also learn about ~= (whitespace seperated) ^= (starts with) $= (ends with) and *= (contains) all of which are valid types of CSS selectors.
But wait, you say! How does “facebox-” translated to “facebox[.my_class]“?!?
It doesn’t.
I find facebox[.my_class] to be really unwieldy, so I changed it to facebox-my_class. This way, you can also put additional rel data in the link if you need, as long as facebox comes first.
All of these are valid:
rel="facebox-my_class help"
rel="facebox-my_class"
rel="facebox"
So, in light of this, we have to change the regex match in the click_handler from:
// support for rel="facebox[.inline_popup]" syntax, to add a class
var klass = elem.rel.match(/facebox\[\.(\w+)\]/);
if (klass) klass = klass[1];
to
// support for rel="facebox-inline_popup" syntax, to add a class
var klass = elem.rel.match(/facebox\-(\w+)/);
if (klass) klass = klass[1];
And then in your CSS to use the class:
#facebox_content.my_class{
height: 300px;
width: 500px;
}
Done and done!
(As a smaller bug fix, I noticed that the original code never deletes previously added classes — only appends them, so I added this line to the reveal function to make sure that the classes were reset each time you opened a FaceBox
contentWrapper.className = 'content';
Stylize that Sucker!
So, problem 2 is that FaceBox has no way to stylize the lightwindow contents on a per-link basis — you have to define a whole new class for each type of lightwindow that you want. This in itself is not so bad, but it would be nice to have that slight extra amount of customizable power.
So, what I did is just add a “style” variable to each of the reveal/ajax/etc function calls, and had it append that style to the facebox_content div.
reveal : function(data, klass, style){
....
//Set H/W or any other styles (also clears styles)
contentWrapper.writeAttribute('style', style);
....
If you’re calling the lightbox from code, you just add whatever style attributes you want to the call
facebox.ajax('mypage.html', 'my_class', 'height:300px;width:400px;'
If you’re using the automatic calling from the rel tag, then you have to add a rev tag, and put your stylesheet in there. Anything you put in the rev tag will be copied to the style attribute of the contentWrapper
<a href="mypage.html" rel="facebox-my_class" rev="height:300px;width:400px">Link</a>
Simple as that!
(It should be noted however, that the height and width of the content_window does not take into account the borders, padding and footer of the FaceBox, so be sure to leave yourself a little margin of error)
No Scrollbars?!?
You still with me? It’s been long, I know, but just hang with me a little more. This is the last point.
So, as I said earlier, there’s a problem(?) with FaceBox wherein long content just makes the FaceBox longer until all the content is shown. As this system is made for display quick banners and small ajax pages and what not, it’s understandable that it would be left out, but why not put it in when it’s so damn simple?
So how do you do it?
//facebox.css
#facebox_content{
overflow: auto;
}
That’s it.
What this does is allows the FaceBox to extend to show all the content normally, but if you decided that the FaceBox needs a certain height (through a class or styling) then the FaceBox will be set to that height, and anything that goes over that height will be scrollable.
That Damn Simple.
In Conclusion
Not much of an “In Conclusion.” I’ve pretty much said all I want to say, so all there is left is to check out the codes~
If you find any problems or bugs, feel free to drop me a comment!

I’ve updated my code with a newer version:
Version 1.2 which includes such awesome things as full IFrame support and better support for classes and styles! You can check out the
Article, or just
download the code from here!
The way the code is used has been changed, so be sure to read the README!
Download FaceBox v 1.1 (Open sourced under the MIT License)