jQuery: expandable image gallery

If we play carefully with CSS absolute and relative positioning, we can actually get some interesting effects through the animate() method. This is the case of an expandable image gallery: you click on a magnifying glass, a box appears at the bottom of the gallery and then the current image moves from its position to the center of the box with enlarged dimensions. Finally, you click on a closing button and the image gets again its original position and dimensions while the box disappears. This can be actually done by first declaring the image as relatively positioned, then absolutely positioned and finally relatively positioned again. Let's start with our basic markup:

<div id="gallery">

 <ul>
  <li>
   <img src="pics/1.jpg" alt="" />
   <p>
   <a href="#" class="expand">
   Expand
   </a>
   </p>
  </li>
  <!--other images-->
    </ul>
    
    <div id="expanded">
  <a href="#" id="close">Close</a>
 </div>
</div>

We have only to make our gallery wrapper as relative to create a contextual positioning for the images:

#gallery {
 width: 315px;
 height: 400px;
 position: relative;
 margin: 0 auto;
}

#gallery ul {
 width: 100%;
 height: 133px;
 margin: 0;
 padding: 0;
 list-style: none;
}

#gallery li {
 float: left;
 width: 105px;
}

#gallery li img {
 display: block;
 width: 100px;
 height: 90px;
 margin: 0 auto;
 position: relative;
 z-index: 11;
}

#gallery li p {
 margin: 0;
 padding-top: 5px;
}

#gallery li p a.expand {
 width: 28px;
 height: 28px;
 display: block;
 margin: 0 auto;
 background: url(expand.png) no-repeat;
 text-indent: -1000em;
}

#expanded {
 width: 290px;
 height: 257px;
 margin: 0 auto;
 position: relative;
 background: #e0e0e0;
 top: 10px;
 display: none;
}

#close {
 position: absolute;
 top: -10px;
 right: 0;
 width: 28px;
 height: 28px;
 text-indent: -1000em;
 background: url(closeimg.png) no-repeat;
}

Now you may say: "Wait a minute! We got only one closing button and several images. How we can associate the closing action with the current image?". We can accomplish this task using a progressive index starting with -1 and stored using the data() method. Each time we click on the magnifying glass, the current index is incremented and then stored in the closing button:

$(function() {

  var i = -1;

  $('a.expand').each(function() {

    var $a = $(this);
    var $img = $a.parent().prev();
    var $expanded = $('#expanded', '#gallery');
    var $close = $('#close', '#expanded');
    
    $a.click(function(event) {
      
      i++;
    
      $close.removeData('i');
      $close.data('i', i);
    
      $expanded.fadeIn(1000, function() {
      
        $img.css('position', 'absolute').animate({
          top: 171,
          left: 47,
          width: 220,
          height: 200
        }, 'slow');
      
      });
    
      event.preventDefault();
    
    });
  
  });
  
  $('#close', '#expanded').click(function(event) {
  
  
    var $close = $(this);  
    var index = $close.data('i');
    $('img', '#gallery').eq(index).
    css('position', 'relative').
    animate({
      top: 0,
      left: 0,
      width: 100,
      height: 90
    }, 'slow', function() {
    
    
      $close.parent().fadeOut(1000);
    
    
    });
  
  
    event.preventDefault();
  
  });
  
    
});

When we click on the closing button, the position of the current image is set to relative again so that it moves back to its original position. This happens because in CSS relative positioning always refers to the current position of an element with respect to itself, not to its container or ancestor. You can see the demo below.

Demo

Live demo

This entry was posted in by Gabriele Romanato. Bookmark the permalink.

One thought on “jQuery: expandable image gallery”

Leave a Reply

Note: Only a member of this blog may post a comment.