Skip to content

The simplest lightbox gallery using srcset & sizes for responsive images

Notifications You must be signed in to change notification settings

blinkcursor/mv-gallery

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Minimum Viable Gallery

With growing adoption of srcset & sizes for responsive images we can let the browser do the work of choosing optimum image sources for both the gallery thumbnails and the full size images with just a single <img> definition. We just need a little JavaScript to update the sizes attribute when the layout changes for our lightbox view.

Demo: blinkcursor.github.io/mv-gallery/

<a href="img/nojs-fallback.jpg">
	<img src="img/unsupported-fallback.jpg" 
		 srcset="img/smallest.jpg 400w, img/smallish.jpg 600w, img/small.jpg 800w, img/medium.jpg 1000w, img/biggish.jpg 1200w, img/big.jpg 1400w, bigger.jpg 1800w, biggest.jpg 2400w" 
		 sizes="(max-width: 399px) 100%, (max-width: 599px) 50%, (max-width: 799px) 33.33%, 200px" alt="sample image">
</a>

The sizes definition is for our gallery (thumbnails) view. When the user clicks on a thumbnail we launch a modal lightbox and populate it with a clone of the thumbnail, but before inserting it into the DOM we dynamically update sizes to the value appropriate for the modal and let the browser select the best image source.

For our baseline, sizes for a full-width modal would be 100vw, but we can be smarter than that.

The modal uses max-height: 100% and max-width: 100% to constrain our full-sized images to fit on the screen.

But any image whose aspect ratio is smaller than the screen aspect ratio won't occupy the full width of the screen, and sizes: 100vw will overstate how much width the image will occupy.

Think portrait images on a laptop screen, which might occupy 50% or less of the available width according to sizes, and which results in the browser selecting a much larger image than required.

The problem with portraits

Portrait image in a landscape view

When cloning our thumbnail image we know its aspect ratio which gives us a chance to compute a more relevant sizes value by comparing it to the screen aspect ratio.

Safari (OSX and iOS) is a problem. It has a bug whereby the sizes attribute is present on <img> elements, but the sizes property is missing and any attempt to dynamically update sizes is ignored. As a workaround for Safari we parse srcset ourselves to find the appropriate size and set the src on a new image instead.

To use

The are no markup requirements for your gallery. Just wrap some <img>'s in a container and pass the query selector for your container to mvGallery.init(selector).

The source code is in src/js/mvgallery.js.

It has two dependencies.

  1. src/js/plugins/swipe-detect.js is a crude touch event handler written specifically for mv-gallery to add swiping between images. IRL you might want to use a dedicated touch handling library like hammer.js and modify mvgallery.js accordingly.
  2. parse-srcset by Alex Bell for the Safari bug workaround.

In /dist these are bundled with mvgallery into mvgallery-bundle.min.js, while mvgallery.min.css has the minimal styling required for the modal lightbox. (How you style your gallery is up to you.)

Link to mvgallery.min.css in your document <head> and include mvgallery-bundle.min.js just before your closing </body> tag, then instantiate with mvGallery.init('selector').

What's missing

Nothing fancy here. In production this would benefit from some nice transitions when navigating between images, and use of the History API to allow linking directly to individual images when shared etc.

The demo

As well as concatenating and minifying the source files, the gulpfile includes a task to automatically generate all of the different image sizes from source images found in the src/img directory. The example should be self-explanatory.

About

The simplest lightbox gallery using srcset & sizes for responsive images

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages