Responsive CSS3 Modal Gallery (with JavaScript pagination)

This is version 4. Also see all other versions to see how this gallery evolved.

Version 4 of the responsive gallery uses a small amount of JavaScript to split a large gallery into smaller pages, and load ALL images on demand only, instead of during initial page load. Only small images in the first visible page are loaded by default. This improves performance considerably, but (and its a BIG BUT) most of the gallery is inaccessible if JavaScript is turned off.

Like version 3 (JS on-demand images + keyboard controls), left, right and close (Esc) key navigation is included to move through the image enlargement lightbox. Plus, you can cycle through ALL enlargements regardless of which page is visible.

Click on an image below to bring the gallery to life (and resize the browser window for slinky responsiveness)...

Features

A CSS3, responsive image gallery that;

Please view the source of this web page to grab the JS, CSS and HTML markup, OR see the PHP version.

Pros

Cons

Notes (JavaScript for on-demand images, keyboard controls + pagination)

I won't go through all the evolutionary changes to the gallery again - this version has everything that version 3 (JS on-demand images + keyboard controls) has so you can recap on the notes there.

The main thing I'd like to draw your attention to is the HTML5 "data-src" attribute which now references ALL images instead of the standard "src" attribute. With "data-src" in place, the images will not load until JavaScript changes it to "src". This happens at a few points in the script so that the small images only load when pagination links are clicked (into the visible "page" only), and larger images only load when thumbs are clicked, or when previous/next controls take your there.

To demonstrate the on-demand image script, see this YSlow component report showing only 4 images downloaded - 3 thumbs from the first page of the gallery, plus the header logo (there are 18 gallery images in total!).

UX consideration 1... what happens when JS is disabled?

The deleted chunk of info below can be ignored now that alternative markup is included in <noscript> tags. Thinking along the same lines as the IE7/8 workaround (more on that later), where those users can open image enlargements in a new browser window instead of the modal overlay/lightbox, we can do something similar for folks with JavaScript turned off;

<!--[if gte IE 9]><!--><a onclick="load('img-1')"><!--<![endif]--> <!-- no href - use location.replace('#pic-'+id); in load() function -->
<!--[if lte IE 8]><a href="/path/to/big/image.jpg" target="_blank"><![endif]-->
    <img class="small-img" data-src="/path/to/small/thumb.jpg" width="252" height="160" alt="" />
    <noscript>
         <a href="/path/to/big/image.jpg" target="_blank">
         <img src="/path/to/small/thumb.jpg" width="252" height="160" alt="" />
    </noscript>

    <span><b>Preview</b></span>
</a>

Please note, this is a minimal fallback that only provides a reduced, token gallery for the first page of thumbnail images - there's a bit of a trade-off between performance, and giving non-JS users something to look at. Just to confirm, and paraphrasing the W3C noscript specs, "the contents of the noscript element will load when JavaScript is unavailable", hence why here it has only been provided for some of the thumbs (those in the first page), and not all of the thumbs.

Unfortunately, nothing. The gallery relies on JavaScript to switch in the "src" attribute of all images, so there is no fallback for when it isn't available. The CSS below simply hides it in those cases;

/* #### - extra css for js enhancement - #### */
#gallery { display:none } /* hide gallery if js is disabled */
.js #gallery { display:block; overflow:hidden } /* show gallery if js is on */

UX consideration 2... is it loading?

The "on-demand" image script takes care of the performance dilemma (thumbs up for mobile), but it could leave users with slower internet connections wondering when that big ol' image is going to appear on their screen. So let's add a simple loading spinner to indicate something is happening... Add this to the CSS;

@-webkit-keyframes rotation { from {-webkit-transform:rotate(0deg)} to {-webkit-transform:rotate(359deg)} }
@keyframes rotation { from {transform:rotate(0deg)} to {transform:rotate(359deg)} }
#gallery .overlay:before {
    content:""; position:absolute; top:40%; margin-top:-0.5em; left:50%; margin-left:-2em; display:block; height:3em; width:3em;
    border:0.5em solid rgba(255,255,255,.15); border-top:0.5em solid rgba(255,255,255,.5); border-radius:100%;
    -webkit-animation:rotation .75s infinite linear; animation:rotation .75s infinite linear
    }

This places a CSS pseudo element loading spinner on the #gallery .overlay. It's always present, but then when an image has loaded, the picture will sit in front of the spinner and hide it!

UX consideration 3... how many thumbs?

Although you can have as many thumbnails in a pagination area as you wish, bear in mind that while 20 of them might look pretty spiffy on a desktop monitor, they become a bit unmanageable on small screens - you'll end up with a long column of pics with the pagination links floated way up off the top of the screen. A good way to counteract this (to a degree) is to resize thumbnails using CSS in mobile view, and then reset them for desktop. A happy side-effect of this is that half-size thumbs on small retina displays look ultra crispy! ;) Of course, you still need to be sensible about the number of thumbs to show per page for performance reasons - I'd personally go with 10 or 12 max.

UX consideration 4... where's the grid?

For predictable results, set a max-width on the pagination areas to encourage thumbnail images to fall into a nice neat grid;

#gallery .pagination { max-width:48.75em } /* fix thumbs to grid */

Compatibility

* The :target selector is not supported in IE7/8 but a bit of markup-mashing with IE conditional comments provides a workaround so those users can open image enlargements in a new browser window instead of the modal overlay/lightbox.

<!--[if gte IE 9]><!--><a onclick="load('img-1')"><!--<![endif]--> <!-- no href - use location.replace('#pic-'+id); in load() function -->
<!--[if lte IE 8]><a href="/path/to/big/image.jpg" target="_blank"><![endif]-->
    <img class="small-img" data-src="/path/to/small/thumb.jpg" width="252" height="160" alt="" />
    <noscript>
         <a href="/path/to/big/image.jpg" target="_blank">
         <img src="/path/to/small/thumb.jpg" width="252" height="160" alt="" />
    </noscript>
    <span><b>Preview</b></span>
</a>

* IE7/8 users will not see the magnifying glass icon when they hover over a thumbnail. However, there is fallback for a plain "Preview" bar that they will see instead.

I haven't been able to test in other browsers/devices but feedback is always welcome. Contact me if you spot anything hinky.

Acknowledgement

Inspired by the "CSS3 Modal Popups" tutorial at Script Tutorials. Starter pagination JavaScript sourced via a JSFiddle.

Related

Freebies

Looking for more freebies for your website? Grab a bunch of free PHP, CSS and JavaScript goodies, from flat file CMS' to RSS managers to responsive CSS menus, galleries and sliders.