Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

CSS

Arrange responsive images side by side with different heights and on different lines.

I would like to display images side by side, each image having width of 100%, and 4-5 images approximately placed on each line. The problem is that all images are of different heights and the next line of images do not start from the 1st place rather occupies free space as shown in picture attached!.

I have tried to use clear property as well the the regular clearfix code on parent container and its direct children too, but still doesn't work the way it should.

I have also used Masonry.js to get that result, but still not able to get through.

The output is right now like this: (https://dl.dropboxusercontent.com/u/74143916/imageplacement.png)

Desired Result: (http://i.stack.imgur.com/ZSbiP.png)

CSS:

html, body, div, img {padding:0; margin:0; border:0;}
.container {width:100%;}
.item {width:19.5%;display:inline-block; margin-right:-3px;}
.item img{width:100%; vertical-align:top;}

HTML:

<div class="container">
<div class="item">
 <img src="http://placehold.it/350x150">
</div>
<div class="item">
 <img src="http://placehold.it/350x200">
</div>
<div class="item">
<img src="http://placehold.it/250x100">
</div>
<div class="item">
<img src="http://placehold.it/300x250">
</div>
<div class="item">
<img src="http://placehold.it/150x150">
</div>
<div class="item">
<img src="http://placehold.it/250x350">
</div>
<div class="item">
<img src="http://placehold.it/300x250">
</div>
<div class="item">
<img src="http://placehold.it/150x150">
</div>
<div class="item">
<img src="http://placehold.it/250x350">
</div>
<div class="item">
<img src="http://placehold.it/300x250">
</div>
</div>

3 Answers

Grant Zabriskie Hi I just figured out the problem. The masonry layout was loading much before my images were loaded, even after placing the javascript code at the end of the html file. This layout function loading before the images load was causing the overlap problem initially, after I re-size my browser window the layout function was called again and again as and when the images re-sized, that's y at that time the layout was working. So, the solution to this problem is using the "imagesLoaded" function and also not to forget to include the imagesLoaded Javascript file which is available on the same Masonry Website. Hope this topic helps a few other people out there like me. All the Best guys.

Grant Zabriskie
Grant Zabriskie
11,017 Points

Good work! Glad you figured it out!

Steven Parker
Steven Parker
221,310 Points

What if you introduced a class to represent a "column" which was inline-block, and let the images themselves stack vertically in them? You could also remove the "item" class to simplify:

CSS

html, body, div, img {
  padding:0;
  margin:0;
  border:0;
}
.container {
  width:100%;
}
.column {
  width:19.5%;
  display:inline-block;
  vertical-align:top;
}
.column img {
  width:100%;
  padding:3px;
  vertical-align:top;
}

HTML

<div class="container">
  <div class="column">
    <img src="http://placehold.it/350x150">
    <img src="http://placehold.it/350x200">
    <img src="http://placehold.it/250x100">
  </div>
  <div class="column">
    <img src="http://placehold.it/300x250">
    <img src="http://placehold.it/150x150">
  </div>
  <div class="column">
    <img src="http://placehold.it/250x350">
  </div>
  <div class="column">
    <img src="http://placehold.it/300x250">
    <img src="http://placehold.it/150x150">
  </div>
  <div class="column">
    <img src="http://placehold.it/250x350">
    <img src="http://placehold.it/300x250">
  </div>
</div>

Is that what you're looking for?

No actually this technique is a temporary method to solve a problem not a full proof method. Suppose that tomorrow my second image in the first column might change and the image height is very big, then what, again will I go and change my html page layout . We have to think of a way to style our align our images as shown in the desired images result only through css. Also there is a big gap between 250x350 image at the 2nd line and 250x100 at the 1st line, that problem will always remain with image that have varying heights. Thanks for the solution, but I would like to have a much more flexible solution which accommodates for all sizes of images like we see in pinterest site. See if you can help me with that.

Hi Steven, looking at the solution given by Grant, I think your CSS was much closer to the desired effect, but its just that I told you that we should not alter our HTML. But anyways, thanks for inputting your idea, makes us learn from our mistakes and other people's ideas.

Grant Zabriskie
Grant Zabriskie
11,017 Points

Hi Shabbir!

So, the layout affect you are going for is called the "Masonry" layout in the CSS world. There's a Javascript library called masory.js that can create this effect for you.

http://masonry.desandro.com/

Here's one pure CSS method that I've come across that seems to be pretty popular. You can check it out at:

http://sickdesigner.com/masonry-css-getting-awesome-with-css3/. Demo: http://sickdesigner.com/demo/css-masonry/css-masonry.html

This method is pretty good, but has the limitation that the items flow from top to bottom, column by column (see the Demo for an example). So far as I can tell, there is no pure CSS way to get the masonry effect with the items running left to right, row by row.

Other examples I've seen require you to know the width and height of your container and all your images, which you might not ever know for sure in a dynamic application where the images are always different. Also, such approaches would require you to write a lot of media queries if you want it to be responsive.

Do a Google search for "masory js," "css masory layout," or "pure css masonry layout" for some more ideas and examples I might have missed.

Thank You Grant for the help. The above did work for me, but still its not so robust as I could see a few problems while I was re-sizing my browser window. Then I also tried Masonry.js, that works fine in all conditions regardless of the window size, but there is one small issue, I suppose u might have solved that problem and can help me out with it. Whenever I load my page containing this javascript file and see what's going on in the Chrome Dev Tools, all images are placed absolute position automatically by the javascript, now the problem is the images that should go in the second row, instead they all overlap the 1st row images. Now, when i re-size my browser window, the images all come back into place where they should be, again when i refresh my page, the same overlapping problem comes.