Building your own Lightbox with Javascript

Why write your own lightbox?

The simple answer is: to learn how it’s done. If you’re going to use if for an image gallery, embed flash and videos or even to load Ajax content you are probably better off using one of the many existing lightbox plugins (Thickbox, FancyBox). If you plan to use a lightbox for more complex applications like the admin back end of a cms (see the future Drupal 7 Admin Panel ) then you should either fully understand every line of your plugin or write your own.

This tutorial assumes some knowledge of Javascript. If you are just starting Javascript I highly recommend watching Jeffrey Way’s Javascript from null video series on nettuts.com.

Why and when to use a Lightbox ?

If used right, a lightbox (aka overlay window, modal window) can benefit both the usability and the user experience. Let’s say you visit a blog that contains both public and member-only articles. As a new visitor you click through the categories and decide to register in order to view the an article that requires registration. You click the Register button that takes you to a new page. A questions that I always ask myself at this point is “How do I get back to the category page I was looking at before clicking Register?”. A usable website would keep track of where the user was before clicking Register and redirect him back to that page after the registration. The problem here is that the user has to do unnecessary thinking. If instead we used a lightbox for the registration, the user will always see the category page through the semi-transparent lightbox window. This creates a more fluid user experience. Steven Krug’s “Don’t make me think” is a great book that will give you more insight into how users think.

Regardless of how you use a lightbox you should always make sure the functionality is there when javascript is disabled. Take digg.com for example, if you have Javascript enabled and you click Login you will get a lightbox that promps for your username and password; if you disable Javascript and click Login you will be taken to a separate page that has the same login form. This is called progressive enhancement and digg.com achieves that by linking “Login” to the real login page. When javascript is enabled the link is disabled and the login page is loaded via Ajax. If javascript is disabled the link will take you to the login page.

Building the lightbox – XHtml/CSS

For the purpose of this tutorial I will embed all my CSS rules and Javascript directly into the markup. This is not a good practice for final websites – all CSS sheets and Javascript files should be placed in external files.

The concept behind a lightbox is simple: the overlay semi-transparent window is a div that extends 100% of the width and height and sits on top of all the other divs on the page.

  • lightbox_overlay is the semi-transparent div that covers everything
  • lightbox_content will hold the content to be displayed in the lightbox
  • close the link that will close the lightbox (once it’s open)
  • open the link that will open the lightbox
<style type="text/css">  
.. CSS Rules here
</style>

<script type="text/javascript">  
.. Javascript goes here
</script> 

<div id="lightbox_overlay">  
</div>

<div id="lightbox_content">  
<p>Some random content here</p>  
<a href="#" id="close">Close</a>  
</div>

<h1>Lightbox Tutorial</h1>

<p>  
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vel velit arcu. Pellentesque consectetur urna at sapien malesuada feugiat. Ut commodo urna vel est accumsan vel lacinia justo volutpat. Vivamus congue nunc malesuada nunc sodales ac scelerisque massa bibendum. Ut tempus ullamcorper euismod. Nullam vulputate, tellus ut scelerisque feugiat, lectus sapien pulvinar augue, dignissim lacinia urna dolor ut metus. Mauris id placerat velit. Fusce ac mauris vel mi dignissim ornare vitae vel sapien. Mauris tempus nisl pretium tortor tincidunt vel cursus enim porttitor. Etiam congue lacinia est fermentum pellentesque. Fusce malesuada congue eros, ac rhoncus tellus lobortis hendrerit.  
</p>

<a href="#" id="open">Open lightbox</a>  

Now let’s style the lightbox using CSS. You will notice that I used display: block for both the content and the overlay window. I did that to keep the lightbox visible for styling – later we will use Javascript to change this display property from none to block.

body { margin: 0 auto; width: 960px; padding: 0;}

#lightbox_overlay {
position: fixed;  
display: block; /* will be changed to none */  
top: 0;  
left: 0;  
width: 100%;  
height: 100%;  
background-color:#000;  
z-index: 100;  
filter:alpha(opacity=80);  
opacity: 0.80;  
}

* html #lightbox_overlay { /* ie6 hack */
position: absolute;  
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');  
}

#lightbox_content {
position: absolute;  
display: block; /* will be changed to none */  
top: 25%;  
left: 25%;  
width: 50%;  
height: 50%;  
padding: 16px;  
background-color: white;  
z-index:1002;  
overflow: auto;  
}

Notice I used filter:alpha(opacity=75) to specify the opacity in IE and hack to display the overlay properly in IE6.

Interacting with the lightbox – Javascript

This is not a very robust lightbox.  In the second part of this article I will show you how to re-create this with jQuery and make it more flexible.

// create variables for elements involved in interaction
var anchor_open = document.getElementById('open');  
var anchor_close = document.getElementById('close');  
var lightbox_overlay = document.getElementById('lightbox_overlay');  
var lightbox_content = document.getElementById('lightbox_content');

// function that displays lightbox
function openLightbox() {  
  lightbox_overlay.style.display = 'block';
  lightbox_content.style.display = 'block';
}

// function that hides lightbox
function closeLightbox() {  
  lightbox_overlay.style.display = 'none';
  lightbox_content.style.display = 'none';
}

// function to add an event cross-browser
function addEvent(obj, evt, fn, capture) {  
  if ( window.attachEvent ) { // if true then we have IE browser
    obj.attachEvent('on' + evt, fn);
  }
  else {
    if ( !capture ) capture = false;
    obj.addEventListener(evt, fn, capture);
  }
}

// using addEvent function to bind click events
addEvent(anchor_open, 'click', openLightbox);  
addEvent(anchor_close, 'click', closeLightbox);  
addEvent(lightbox_overlay, 'click', closeLightbox);  

The problem with binding events to elements is that IE uses attachEvent while the rest of the browsers use addEventListener. The function addEvent simply detects if the attachEvent method is available in order to test if the browser is IE.

Credits

The function for binding an event for IE was presented in the Javascript from null video tutorials.
The CSS hack for IE6 is taken from the Thickbox CSS file.