Masonry layout with css grid

user2950602 picture user2950602 · May 11, 2017 · Viewed 9.2k times · Source

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:

full codepen here

Answer

andybarefoot picture andybarefoot · Sep 26, 2017

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