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)
Asked
Active
Viewed 1,330 times
-1
-
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 Answers
0
You can use CSS-grid
to do this.
- Specify the number of columns.
grid-template-columns: repeat(3, 1fr); /* a 3 column layout */
- Trick #1: Create 1px rows for your grid (heyyy it's a pixel grid!)
grid-auto-rows: 1px;
- 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>