reptile7's JavaScript blog
Wednesday, December 21, 2011
Introduction to the Lightbox Image Viewer
Blog Entry #236

In today's post we will take up HTML Goodies' "Web Developer Class: How To Use the JavaScript Lightbox Image Viewer" tutorial, which was authored by Scott Clark. The lightbox image viewer spotlighted by the tutorial was created by Lokesh Dhakar.

The lightbox image viewer is what we might have called a layer-based application back in the day. In response to a user action - e.g., clicking a link or thumbnail image - the lightbox image viewer displays a viewport-centered image on a page-covering overlay. The overlay and the image it surrounds seem to be above the page because of the overlay's translucent background, and they are in fact removed from the underlying document's normal rendering flow by virtue of their absolute positioning although they are still very much part of that document.

The tutorial formerly demonstrated the lightbox image viewer in a 600px-by-500px iframe just below its first paragraph; an incomplete version of the iframe's isolated src page is archived here. I must say, those were some handsome snakes in those photos!
December 2016 Update: As noted in Part 7 of this series, the tutorial demo and the site that hosted it are no longer on the live Web; as it happens, however, I downloaded those snake photos way back when, and I plan to restage the demo in a future post.

A practical example:, an archive of CD cover art, uses the lightbox image viewer for its "zoom" feature. Can you pick out Phil Collins in this photo?

Perhaps I should give you my own demo before we get rolling. Click on the thumbnail photo of Reggie the alligator:

Reggie the alligator

The lightbox/ package

The tutorial links to a downloadable lightbox/ .zip package that contains most of what you'll need to assemble the lightbox image viewer. The lightbox/ package holds five files:
(1) A lightbox.js script codes the lightbox image viewer's structure, its behavior, and some of its styles; those styles are supplemented by
(2) a lightbox.css style sheet that specifies additional styles.
(3) An 80%-opacity overlay.png image is tiled to form the overlay background.
(4) A close.gif image serves as a close button for the lightbox image viewer.
(5) The lightbox image viewer briefly displays a loading.gif animated gif while it fetches its main image.

At the top of the lightbox.js script is some metadata in which the author requests that we leave my name and link in place. Actually, there are two Lokesh Dhakar-related links in the metadata and both of them are outdated. I'm sure that Lokesh would want us to update those links:
(1) Lokesh Dhakar's Web site is no longer at, it's at
(2) For more information on the script, don't visit, visit

Code-wise, the only thing missing in the package is an HTML template - let's call it lightbox.html - for providing an interface to the user; that's where the tutorial comes in...

The HTML interface

The tutorial offers two interfaces for the lightbox image viewer: a thumbnail image interface and a link interface. In both cases you will need a parent anchor element
(a) whose href attribute points to the lightbox image and
(b) with a rel="lightbox" attribute.
Optionally, (c) equipping the anchor element with a title attribute will allow you to place a caption below the lightbox image's lower-left-hand corner.

<a href="myPhoto.jpg" rel="lightbox" title="Caption for myPhoto.jpg"> ...Thumbnail image or text... </a>

The rel="lightbox" attribute does not specify a recognized link type; rather, the lightbox rel value will later serve as an identifier, a purpose for which the author should have used a class="linkClass" attribute.

Techrtr in the tutorial comment thread brings up the issue of thumbnail image creation:
I assume you have to create the thumbnail but none of the instructions I've seen that describe how to use Lightbox mention creating it.
Sure enough, for both of the tutorial's thumbnail image examples, the anchor href attribute and the img src attribute point to different images. This is totally unnecessary: per the Offering One Image section of HTML Goodies' "So You Want A Thumb-Nail Image, Huh?" tutorial, we can load the main images into the thumbnail img placeholders if the latter are equipped with suitably scaled width and height attributes*, e.g.:

<a href="punk_the_burmese.jpg" rel="lightbox" title="Baby the Albino Burmese Python">
<img width="100" height="66" src="punk_the_burmese.jpg" alt="" />

*It's odd that Scott didn't do this given that all four of the baby_full_belly/punk_the_burmese photos have a 1.5:1 width/height ratio; the main photos scale down perfectly. The examples on Lokesh's "Lightbox JS" page also feature different main/thumbnail photos; adding insult to injury, the "handstand incident" thumbnail photo links to the "Lokesh, Jess, Brian, and Steph" main photo and vice versa.

Importing lightbox.css and lightbox.js

An HTML document can import an external style sheet via either the link element or the style element; Lokesh and Scott choose the former:

<link rel="stylesheet" href="lightbox.css" type="text/css" media="screen" />

• The rel="stylesheet" attribute and the absence of a title attribute stipulate that lightbox.css is a persistent style sheet whose rules "must apply" unless the user disables it.
• The media="screen" attribute is unnecessary as screen is the default value of the media attribute.
• The equivalent style element formulation would be:
<style type="text/css">@import "lightbox.css";</style>

We will discuss the lightbox.css rules when we work through the lightbox.js showLightbox( ) function.

To the best of my knowledge, an external script can only be imported via the script element:

<script type="text/javascript" src="lightbox.js"></script>


Before lightbox.html loads, the lightbox.js script variabilizes the loading.gif and close.gif file names and calls an addLoadEvent( ) function:

var loadingImage = "loading.gif";
var closeButton = "close.gif";

(In the aforementioned lightbox.js metadata, Lokesh lists all of the lightbox.js functions and identifies the lightbox.js function, addLoadEvent( ), whose top-level call sets up the rest of the script action. If only more authors did this!)

Here's the addLoadEvent( ) function:

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != "function") {
        window.onload = func; }
    else {
        window.onload = function( ) {
            oldonload( );
            func( ); } } }

The above function is the original version** of the "Executing JavaScript on page load" addLoadEvent( ) function that was crafted by Simon Willison and is highlighted by HTML Goodies' "Using Multiple JavaScript Onload Functions" tutorial. In brief, the addLoadEvent( ) function is a cross-browser, IE 5 for Mac-accommodating way to assign a function reference - in our case, a reference to an initLightbox( ) function - to the onload property (event handler) of the window object without overwriting a previous window.onload = some_other_function; assignment.

**The current addLoadEvent( ) conditionalizes the oldonload( ) call in the else clause:

if (oldonload) { oldonload( ); }

this quashes a runtime error when using IE 7 according to the Update 28th May 2006 on the "Executing JavaScript on page load" page.

(BTW, if you were to also equip the body element with an inline onload attribute -
<body onload="yet_another_function( );"> -
then that attribute will overwrite the addLoadEvent( ) window.onload assignment, so don't do that.)

The state-of-the-art way to do this sort of thing is via the addEventListener( ) method

window.addEventListener("load", some_other_function, false);
window.addEventListener("load", initLightbox, false);

whose IE support began with IE 9.

Of course, if initLightbox( ) is the only function that is 'listening' for window load events, then the addLoadEvent( ) function is superfluous and a simple window.onload = initLightbox; statement is all we need.


We're ready to put the initLightbox( ) function under the microscope, and that could take a while, so let's save it for the next entry.


Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)