How to Make Better Modal Windows with Lightbox
Published February 12th, 2006 in GeneralIt started with LightboxJS by Lokesh Dhakar; he created a script you could use to overlay images on your page. Then ParticleTree modified the script to let you create a modal window. Then PJ Hyett posted a stripped down, simplified version of the script.
I liked all of those, and I think the lightbox/modal dialog window is a good UI widget to have. So I created my own version of the script. It’s more abstracted than any of the previous ones, and lets you create a modal window (or more than one) on a page really easily.
Download the source. It including the scripts, the css and the various images you’ll need. (02/13 NOTE: updated sources to fix some IE bugs).
Here’s how you use it:
Include the scripts and the css in your page:
Then, create a hidden div somewhere on your page that holds the contents of your modal window, like this:
Then create a link that triggers the lightbox:
<a href="#" onclick="new Lightbox.base('mybox'); return false">Open the lightbox!</a>
That’s it. The script will automatically add everything else, including the little close icon in the upper left of the lightbox.
Options:
– you can choose to have the lightbox close when the user clicks anywhere else on the dimmed-out screen (I call this area the overlay). This is off by default. To turn it on, do this:
new Lightbox.base('mybox', { closeOnOverlayClick : true })
– you can specify the id of an external control to close the lightbox (in addition to the close-box icon), like this:
new Lightbox.base('mybox', { externalControl : 'cancel'})
- by default the lightbox is assigned the class of “lightbox”. You can change this if you want, as long as you remember to change the css accordingly.
new Lightbox.base('mybox', { lightboxClassName : 'myClassName'})
You can do as many of these as you like on a page. The script closes any that are open before opening a new one, so can only have one open at a time. The function that closes any open lightbox windows is Lightbox.hideAll(). You can call this anytime to close all open lightbox windows.
Feel free to reuse, distribute and modify this code as you wish. If you do something cool with it, I’d love to know. Remember that I whipped this up this morning while listening to A Prairie Home Companion, and also that I’m far from an expert in Javascript, so it is likely to have to kinks that need working out.
UPDATES:
Made some fixes thanks to some feedback in the comments. The script now uses no images, and should work as expected in IE6 (and 7, if you have it).
Your version has a major issue. When I scroll down the page, then click your demo link, the overlaying opacity background image doesn’t cover the entire browser window. It only covers what you’d see if you hadn’t scrolled the page at all. This is in Firefox 1.5 and Safari for OS X.
In IE6 for Windows, the opacity background doesn’t display at all.
Hmm…good point. Actually it looks like PJ’s version has that problem too. It’s because the overlay div is set to 100% height and width, but that just takes into account the original viewable area of the window. I’ll see what I can do.
Fixed! Just needed to add some code to stretch the overlay all the way down. I’m still looking into the IE6 windows thing. I’ll post the new source later today.
Your update says it should work as expected in ie6 & 7. Not sure if you put that up there before your last comment or not.
Anyway, I get the popup window content, but not the background overlay in IE6 Win.
Darn! I can confirm that the updated code does not work in IE 6.
Sorry guys, missed these comments in my moderation queue… I’ll take a look as soon as I can.
The example link doesn’t seem to be going anywhere.
Yep..some of the files got wiped out when I switched themes this week.
Alright, I’ve got it partly figured out…something in K2’s stylesheet (the new Wordpress theme I’m using) is causing the lightbox div to center incorrectly on the page. Having trouble pinpointing exactly what, though…I know if I disable the entire K2 stylesheet the lightbox appears as it should. I’ll keep working on it…but the script should work fine on most other sites.
Thanks so much! I’m really looking forward to using it. I have one weird problem that I wondered if you knew how to overcome: I’m using a Yahoo! Map and I want to use the lightbox for users to fill out a form. The lightbox shows on top of the yahoo map in Firefox(which is what I want, but the lightbox overlay shows behind the map in IE which means you can’t read the document. You can find an example here: www.bittercyclist.com/maps/accmap.php
One more thing… I found an article that basically says you can’t use lightbox with DIVs like the Yahoo Map in IE because IE has problems. See http://www.brainjar.com/css/positioning/default5.asp. This article explains that z-index just doesn’t work right with DIVs containing flash, for example. Any work around?
Hi Brandon, I think it has to do with the fact that the z-index css attribute has not effect on embedded Flash objects. So even though the overlay has a higher z-index than the Flash movie (in your case, the Yahoo Map), the Flash gets stacked above everything else.
One way to get around this (I think), would be to modify lightbox.js to automatically look for any flash objects and hide them when the lightbox is activated (and then show them again when it’s closed).
This is actually pretty easy to do, thanks to prototpye.js. It would look something like this:
//first put all your flash in divs with a class name of your choice//in this case i'll use
<div class="flash">
flashObjects = document.getElementsByClassName('flash')
flashObjects.each(function(object){
Element.hide(object);
})
</div>
This would hide them (just put it in the “initialize” function of Lightbox.base).
To show them again, you’d do:
flashObjects = document.getElementsByClassName('flash')
flashObjects.each(function(object){
Element.show(object);
})
And put that in the Lightbox.base.hideBox() function.
Hope that helps.
Thanks so much! I’ll try it out at lunchtime! Unfortunately, I have to work now (non-web development).
It works, but the effect of the light box is totally diminished. I tested the lightbox with the Yahoo AJAX and Google versions, and there is no problems.
Thank you very much for the script. I love how you have abstracted things to make it easier to use. But unfortunately I seem to have the same problem in IE6 on Windows XP. I get the pop up content, but the background overlay does not cover the page, it only seems to cover a very small portion of the page.
I’ve been struggling a little bit with Lightbox.js and have even seen it crash Mozilla completely. Your implementation looks interesting, I am testing it now and I see that in Opera 8.52 the background does not completely disappear when I close the lightbox overlay. I have either scroll the window to get back the native page colors, or change focus to another window and back again.
I’ve been playing around with Bruno’s script in IE 6 and Firefox 1.5. Everything works fine in Firefox 1.5, but in IE6 the overlay does not cover the entire page and in some cases I don’t see it at all. The problem occurs in IE when you put a ‘lightbox’ div (div that you will popup using lightbox) within another div that does not cover the entire page. If you put the lightbox code right after the ‘’ tag and make sure that it’s not within any other div, then you shouldn’t have problems. Unfortunately I could not do that since I created web pages on the fly from a servlet and moving the divs to the top would require a lot of changes.
Also in IE, selects aren’t hidden and display above the ‘lightbox’ div, so I fixed that by hiding all selects within the page then showing any selects within the ‘lightbox’ div.
Another issue I saw in IE is you could scroll up and down the page and since the lightbox doesn’t cover the entire length of the page, I had to prevent the user from being able to do so. So I prevented that from using code I’ve seen in other lightbox implementations.
So after a little bit of work and testing, I made the lightbox work on my system in IE 6 and Firefox 1.5 no matter if you put the ‘lightbox’ div within another div. I also check for CSS styles top, left, width and height and added code to work with percentage and/or pixel values. This is something I just hacked together, so there are definitely many enhancements, fixes one could make. The code is shown below.
Lightbox code: