In this tutorial I'm going to show you a simple implementation of a lightbox effect with jQuery. To understand the techniques presented here, you should be familiar with the concept of CSS positioning. Anyway, don't worry about it because I'll try to explain it to you in the clearest way possible. If you're ready, we can get started.
Structure of a lightbox
The HTML structure of a lightbox is made up of two components: an overlay element and the lightbox element itself. The lightbox element will contain a link for closing the opened boxes, an enlarged version of the selected image and a brief caption for the image.
The overlay element will cover the entire viewport and must be semi-transparent so that the rest of our page will shine through. The overlay must come before the lightbox in the source. Both the overlay and lightbox element must be inserted just before the closing tag of body
, that is, they must be the last elements in the page structure.
Here's our structure:
<body> <!--other page elements--> <div id="overlay"></div> <div id="lightbox"> <a href="#" id="close">Close</a> <img /> <p></p> </div> </body>
Both the paragraph and the image must be empty, because we're going to set their attributes and text content depending on the selected image. This structure will be dynamically inserted via jQuery when the DOM has finished loading.
CSS styles for the lightbox
Both elements must be absolutely positioned within the viewport. Before using CSS absolute positioning, we have to prepare our page to make sure that its dimensions are set to their full extension:
html, body { margin: 0; padding: 0; width: 100%; height: 100%; min-height: 100%; } body { position: relative; font: 100% Arial, sans-serif; background: #fff; color: #333; }
We set position: relative
on the body
element to be sure that our elements will take that element as a reference.
Our overlay element must have full dimensions and cover the entire viewport:
#overlay { width: 100%; height: 100%; min-height: 100%; background: #666; position: absolute; top: 0; left: 0; }
The opacity of this element will be later set through jQuery. Instead, our lightbox element will be horizontally and vertically centered within the viewport:
#lightbox { width: 510px; height: 462px; position: absolute; top: 50%; left: 50%; margin: -231px 0 0 -255px; background: #fff; border: 5px solid #999; } #lightbox #close { width: 30px; height: 30px; display: block; position: absolute; top: -15px; right: 0; text-indent: -1000em; background: url(close.png) no-repeat; } #lightbox img { width: 90%; margin: 0 auto; display: block; height: 400px; padding: 20px 0 0 0; } #lightbox p { width: 80%; margin: 0 auto; padding: 5px 0; font-style: italic; text-align: center; }
This CSS technique is simple: given an element with stated dimensions, first set its top
and left
properties to 50%, and then use a negative value for the top and left margins equal to the half of its height and width, respectively.
The jQuery code
First we need to insert our lightbox structure, set the opacity of our overlay element and hide everything:
$(function() { var lightboxHTML = '<div id="overlay"></div>' + '<div id="lightbox">' + '<a href="#" id="close">Close</a>' + '<img/>' + '<p/>' + '</div>'; $(lightboxHTML).appendTo('body'). hide(); $('#overlay').css('opacity', '0.8'); // continues });
Now we need to loop through the links which contain our images, get the src
and alt
attribute of each image to be used on our empty lightbox image and paragraph. We attach a click
handler to each link to do this:
$('li', '#gallery').each(function() { var $li = $(this); var $a = $li.find('a'); $a.click(function(event) { var src = $a.find('img').attr('src'); var alt = $a.find('img').attr('alt'); $('img', '#lightbox').attr('src', src); $('p', '#lightbox').text(alt); $('#overlay, #lightbox').show(); event.preventDefault(); }); });
We first fill our image and paragraph with their data, and then we show both the overlay and the lightbox elements. Of course we also need to attach an handler to the 'Close' button to hide our elements again:
$('#close', '#lightbox').click(function(event) { $('#lightbox, #overlay').hide(); event.preventDefault(); });
You can see the demo below.
Thank you for making a very easy, stripped down tutorial. I wish I had had this weeks ago.
You're welcome. Thanks for reading this blog. :-)
Thanks for this! Much quicker to build it yourself than to get some bloated, outdated plugin for it.
Awesome. Just wondered if you had any idea how to automatically resize an image based on the browser screen size?
This could be done if you work with $(window).height() and $(window).width() dimensions. You should set a series of conditions and test them against the dimensions of the window object. Anyway, you can accomplish this task also with CSS3 Media Queries:
@media screen and(max-width=800px) {
img {
max-width: 90%;
display: block;
}
}
Of course you should target only the images used as a part of your actual content, not the decorative ones. Use classes for that purpose.
I was having trouble with Lightbox overlay not covering in Safari/Chrome/Explorer 9. The position of relative on the body tag took care of it--DUH! I'll book mark this page so the next time I build a light box, I'll use your simpler code!
wow, ehe, i've been thinking about the same logic as it is, but i'm doubting it might not work, thanks for this blog! You are blessed ! :)
"src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">"
Could you tell me why you need this and what is function?
wow, I spent a couple of hours looking for any tutorial that I would understand and finally I've found one! Thank you so much. Just one question, is it possible to animate an image grow?