-1

How can you create a CSS only Masonry layout, when you know the aspect ratio or height of your tiles in advanced? (classic Pinterest layout)

Don P
  • 60,113
  • 114
  • 300
  • 432
  • in the duplicate there is a section "CSS Grid with item dimensions defined" – Temani Afif Nov 30 '21 at 08:38
  • I think the non-obvious part that their answer doesn't address is given something will a totally variable height, how will you construct a grid that works with it. Using span instead of pixels with 1px row height is an addition that will enable a lot of use cases. If it's too similar can close – Don P Nov 30 '21 at 08:44
  • 1px is a particular case of Xpx and the duplicate already cover the generic case so you replace X with 1px or any value you want – Temani Afif Nov 30 '21 at 08:47

1 Answers1

0

You can use CSS-grid to do this.

  1. Specify the number of columns.

grid-template-columns: repeat(3, 1fr); /* a 3 column layout */

  1. Trick #1: Create 1px rows for your grid (heyyy it's a pixel grid!)

grid-auto-rows: 1px;

  1. Trick #2: Don't use a height on your items, use a grid-row: span {height}.

<div class="item" style="grid-row: span {item_height_here}>

Voila!

Here is a minimum example.

CSS:

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* a 3 column layout */
  grid-auto-flow: dense;
  grid-auto-rows: 1px;
  grid-column-gap: 10px;
}

HTML:

   <div class="container">
      <div class="item" style="grid-row: span 200">
        1
      </div>
      <div class="item" style="grid-row: span 50">
        2
      </div>
      <div class="item" style="grid-row: span 170">
        3
      </div>
      <div class="item" style="grid-row: span 50">
        4
      </div>
      <div class="item" style="grid-row: span 40">
        5
      </div>
    </div>

What this does is create a 3 column layout (you can have any number of columns), and then specify a 1px auto-row grid (hey! it's a pixel grid!).

We then use row-span on each item element to have it grow in size, while still being auto layed out.

Below is a full executable snippet with extra styling.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: dense;
  grid-auto-rows: 1px;
  grid-column-gap: 10px;
}

.item {
  background: rgb(255, 196, 0);
}

.item:nth-child(2n) {
  background: rgb(181, 95, 95);
  /* grid-column: span 9; */
}

.item:nth-child(3n) {
  background: cornflowerblue;
  /* grid-column: span 9; */
}

.item:nth-child(4n) {
  background: lightgreen;
}

.item:nth-child(5n) {
  background: pink;
}

.item {
  /* We center the contents of these items. You can also do this with flexbox too! */
  display: grid;
  justify-content: center;
  align-items: center;
  /* border: 5px solid rgba(0, 0, 0, 0.03); */
  border-radius: 3px;
  font-size: 35px;
}
<div class="container">
  <div class="item" style="grid-row: span 300">
    1
  </div>
  <div class="item" style="grid-row: span 50">
    2
  </div>
  <div class="item" style="grid-row: span 200">
    3
  </div>
  <div class="item" style="grid-row: span 100">
    4
  </div>
  <div class="item" style="grid-row: span 100">
    5
  </div>
</div>
connexo
  • 53,704
  • 14
  • 91
  • 128
Don P
  • 60,113
  • 114
  • 300
  • 432