Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Masonry layout with css grid

I'm trying to create masonry layout using css grid layout. All items in grid have variable heights. And I don't know what items will be. So I can't define grid-row for each item. Is it possible to start each new item right after end of previous in column?

Code I'm trying:

.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 330px);
  align-items: flex-start;
  grid-column-gap: 10px;
  grid-row-gap: 50px;
}

.item {
  background: black;
  border-radius: 5px;
}
<div class="wrapper">
  <div class="item" style="height:50px"></div>
  <div class="item" style="height:100px"></div>
  <div class="item" style="height:30px"></div>
  <div class="item" style="height:90px"></div>
  <div class="item" style="height:80px"></div>
  <div class="item" style="height:50px"></div>
  <div class="item" style="height:70px"></div>
  <div class="item" style="height:40px"></div>

</div>

full codepen here

like image 819
user2950602 Avatar asked May 11 '17 13:05

user2950602


1 Answers

In your question you are setting the height of each item individually. If you are happy to do this then a Masonry layout can easily be achieved with grid.

Instead of setting a height for each item set grid-row-end so that each item spans a certain number of rows.

 <div class="item" style="grid-row-end: span 5"></div>

The height of the item will then depend on the values of grid-auto-rows and grid-row-gap you have set for the grid.

I have made a Codepen here: https://codepen.io/andybarefoot/pen/NaprOB

If you don't want to individually set the grid-row-end value for each item you can use a bit of JavaScript to do it dynamically. I put another "container" div inside each item and measure the height of this container to calculate how many rows the item needs to span. I do this on page load, and again for each item when any images are loaded (as the height of the content will have changed). If you combine this approach with a responsive layout then you should also recalculate on page resize as the width of the columns may have changed and this will affect the height of the content.

Here's my full example with responsive column resizing: https://codepen.io/andybarefoot/pen/QMeZda

If you have items with variable widths you can still achieve a similar effect but the packing of the grid won't be perfect and the item order may be changed to optimise the packing.

I wrote a blog on Medium about this approach in case it is of interest: A Masonry style layout using CSS Grid

like image 108
andybarefoot Avatar answered Sep 20 '22 18:09

andybarefoot