Seamless Responsive Photo Grid

Let's say you have a bunch of images you want to display, and the goal is to get them edge-to-edge on the browser window with no gaps. Just because you think that would be cool. They are of all different sizes. You don't care if they are resized, but they should maintain their aspect ratio. Like this:

Without any CSS at all, the images will line up in a row since they are essentially inline-block:

Rivers of whitespace

But that's not quite what we want. Your mind might go right to some JavaScript solution. Possibly the super cool Masonry project. The problem with the JavaScript option is that it relies on the window.resize event which (to me at least) always makes pages feel sluggish (even if you are hip and do the unbouncing thing).

We can get this working the way we want it to with just CSS. What we need are vertical columns in which to place the images. That way the images will stack on top of each other, and the height issue is moot.

We could wrap equal numbers of images in floated divs, but that's not very easy to keep balanced. The trick is going to be to use Masonry CSS, where the vertical columns are made through the CSS3 property column-count. Yeah, literally, the thing where you can set text in narrow columns automatically.

So as long as the parent with the multiple columns is as wide as the browser window (default) and the column-gap is 0, we got it made in the shade. By setting the images width to 100%, they will take up exactly the width of one column.

But what about when the browser window starts getting narrow? 5 columns might be great for a very large browser window but too many for a smaller browser window (5 images side-by-side might get too narrow). We can fix the problem super easily by having media queries test the browser width and adjust the number of columns accordingly.

Demo

What is cool about this technique to me is that since it's pure CSS, everything happens very smooth and fast. You can resize your browser all around and watch things resize and move very quickly.

What about, you know.

So as far as browser support, it's pretty good, except IE, where it only works in 10+. Otherwise: Firefox 3.6+, Opera 11.1+, Safari 4+, Chrome 10+. Might even be a bit deeper than that.

You might just skip a fallback, because whatever it's not that bad it just has some white gaps. Or you might use the Modernizr/YepNope combo (Modernizr can test for it as csscolumns) to load up jQuery Masonry and see what you can do with that. Or you could test for it and roll your own JS which counts the images and splits them up into equal groups and wraps floated divs around them. Whatever floats your boat.

Super cute cats!!

Totally. They are from LoremPixel. For the demo we grabbed photos in random sizes with jQuery:

This is cool, but I would think, in most cases, you would want your images to load left to right and not top to bottom in columns…. I guess you could sort your images so they would load that way, but that seems like a lot of work unless it’s a static list.

Cool Chris, thanks for this tut. Was discussing this exact format with some development guys the other day, they wanted to minimize any jquery etc for a design they are converting to cms so if we still need to go down this route I will definitely show them this all CSS technique.

Thanks! Although, then it wouldn’t be necessary, for example, to include ‘PHP:’ before the code and then PHP being written inside the ‘code-box’ again. I suggested using rel again because I thought then you’d not have to say ‘PHP:’ or ‘Here’s the CSS:’ before the code-box.

That’s actually a great idea. I can see this being very useful, especially for portfolio type WordPress sites. There could text that appears when an image is hovered to describe the post briefly as well. So many different things could be done with this.

I agree Darryl. My main idea on this is an easy place to mix pix messages (via phone), as well as other photos, designs, graphics and posts. I’ll see what I can do about making one. Not sure how I’m going to get the functions to loop yet keep a single box in place.

Wow! I really love this site. You all offer some good information. I love your use of kittens too. I am a Tucson web designer, so this is all super useful for me. Keep up the good work. I’ll be checking in regularly to get more tips and hints. Thanks.

I’m trying to implement a version of this technique on my site but I think I’m running into a few issues with how webkit handles columns?

I have 6 images / 6 columns at high resolutions and 6 images / 3 columns at lower resolutions. It behaves as expected in Firefox but not in Chrome or Safari. When you return to the higher resolutions it remains at 3 columns?

I’m having a pesky problem with adding some captions though, and I’m wondering if anyone can help.

Here’s the test page: http://souchi.com/pages/celebrity3 As you can see, the text that ends up at the bottom of the longest column won’t stay at the bottom of that column. It wants to wrap to the top of the next column.

Hey Chris, thanks for the genius-ly simple code, took me hours and hours to make work on iphone though; i finally discovered the head must contain meta name=”viewport” content=”width=device-width,initial-scale=1.0″ otherwise the phone sticks think its resolution is in between 800px and 1000px (3 columns, 2 images wide). your code worked on http://iphonetester.com/ and i could re-size my laptop chrome screen and watch it downsize nicely but iphone it was broken… so I think you should add the all important viewport line to your download :)

What is lost when you change the column gap from 0 to something larger? 1px, 2px? I love the effect, but would love the option of a little spacing between images. Tried 1px gap in Firefox and looks okay. Does it affect mobile/responsiveness? Thanks!