Build a Masonry layout (Pinterest layout)
Tags: css, tailwindcss
Published: 2023-07-20 15:11:30

---
title: Build a Masonry layout (Pinterest layout)
published: true
description: 
tags: css, tailwindcss
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-05-15 15:13 +0000
---
Recently, I worked on a side project that allows people to pin videos by link or upload images and I want to display them in the pinterest-style layout. After some research, I have figured out some effective methods to build that layout, including the use of some JS libraries. But for simplicity, I took the only CSS ways.

## 1. CSS columns approach
This approach will leverage the [CSS columns](https://developer.mozilla.org/en-US/docs/Web/CSS/columns) with column-count CSS property that breaks an element's content into the specified number of columns.

``` css
.board-grid {
  column-count: 4;
  column-gap: 1em;
}
``` 
The CSS rules above will style the board into a three column layout without a defined vertical axis.

If you have images with captions, then you want to avoid the stiuation where a the image and caption split across columns, you should use the `page-break-` properties:
``` css
.item {
    -webkit-column-break-inside: avoid;
    break-inside: avoid;
    page-break-inside: avoid;
}
```
It is even easier to build a responsive layout with Tailwind CSS, just use _columns-{count}_ with breakpoint. For example, `md:columns-3` will apply the `columns-3` at only medium screen sizes and above.

```html
<div class="columns-2 md:columns-3 lg:columns-4 gap-6">
  <div class="break-inside-avoid"></div>
  ...
</div>
```

The demo I built by Tailwind CSS, but idea is the same with pure CSS:

{% codepen https://codepen.io/Lehung/pen/wvQywYq %}

The only drawback of this approach is that the ordering of the masonry tiles are vertical — from top to bottom — rather than being shown horizontally from left to right.

## 2. CSS grid approach
The hard part of this approach is that CSS Grid creates two dimensional grids with strict rows and columns, whereas masonry is about letting elements fit themselves into space horizontally and vertically.
![A 2 dimensional grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sux3smncq68sa0defda8.png)

The trick is using `grid-auto-rows` property to sets the unit height for our masonry. Then adjusts each block's height to match the grid with a little bit of math to calculate how many rows they should span.
With H as the height of the block, if we set `grid-auto-rows` value to R, `grid-row-gap` value to G, an appropriate span number (S) for any given block can be calculated by: 
```
S = H / (G + R)
```

For example:
``` css
.board-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 300px);
  grid-auto-rows: 20px;
  grid-gap: 10px;
}
```
The value of `grid-auto-rows` is 20px, and value of `grid-gap` is 10px; so if the height of the element is 300px, it will span 10 rows.
```css
.item{
  grid-row-end: span 10;
}
```
The ideas of this approach I borrowed from https://w3bits.com/css-grid-masonry/.

View details on demo: 
{% codepen  https://codepen.io/Lehung/pen/zYMpWgZ %}

View more about a side project I working on. It is called Mood Opus - a simple mood board that allows people to pin videos by link or upload images and display them in the Masonry layout.   
https://github.com/hungle00/mood_opus