Make a grid of images similar to the flickr feed page.

August 6, 2014

If your some what like me, you should be intrigued on how flickr generates their grid of images on the feed page. How they render all the images, in their correct aspect ratio without breaking the grid nor cropping the images.

Well I had some time over, and decided to try and duplicate the behaviour, it’s actually quite simple.

Here’s the problem, if you just set the height to a specific value, it will break the grid, if you try and let the width flow free, you’ll break the grid in even more places, and the third version is the one we are trying to create.

grid

The trick to create these kind of grids is to take all the images, set them to a specific height (but keeping the aspect ratio) and place them in rows, when you fill one row i.e. you have more images in the row than will fit, you go to the next row and keep doing this until you run out of images.

Now you should have a grid that looks something like the above “height priority”, what’s left to do is to decrease the height of each image in a row simultaneous (while still keeping the aspect) until the width of the row matches the container.

To illustrate, here’s some pseudo-code:

/**
 * Resizes images so they fit within a row based on the width
 * of the container.
 *
 * @param {array}  images An array containing image objects.
 *
 * @return {array} The same array but images should be smaller.
 */
function fitImagesInRow(images) {
	// Keep doing this until the width of all the images are
	// smaller than the container width
	while(getCumulativeWidth(images) > containerWidth) {
		// If the images are still to wide, make each of them
		// a bit smaller.
		for(var i = 0; i < images.length; i++) {
			images[i] = makeSmallerHeight(images[i]);
		}
	};

	return images;
};

Once you’re done with one row, you continue on the next, until you run out of rows.

Easy right?

Now what kind of person would I be if I didn’t leave you with a complete script that does this for you? The class that I’ve made is pretty straight forward and it relies on zero third parties (i.e. you don’t need jQuery or similar libraries).

Here’s how you use the class:

var myImages = [
	{
		image: 'my-first-image.jpg',
		width: '320',
		height: '160'
	}, {
		image: 'my-second-image.jpg',
		width: '640',
		height: '320'
	}, {
		image: 'my-third-image.jpg',
		width: '678',
		height: '678'
	}
];

var myContainer = document.querySelectorAll('.wrapper')[0];

/**
 * @param {array} An array containing all the images
 * @param {element} The container element .
 * @param {int} The start height of each row.
 * @param {int} Border offset. (the right or left side for one item)
 *
 * @return {object}
 */
var myGrid = new BH.ImageGrid(
	myImages, // The images
	myContainer, // The container (we take the width from this element)
	500, // The height we want each row to start from
	10 // How much margin on the images.
);

The code base is readily available on my github account, use it, abuse it. You can also preview a live example here.

Tags