JSFiddle - React, Tailwind, and code Playground
by DefuZe
HTML
<div class="masonry">
<div class="masonry-item">
<div class="masonry-content">
<h3 class="masonry-title">Nesciunt aspernatur eaque similique laudantium a</h3>
<p class="masonry-description">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda modi inventore, totam vero consequuntur, aut animi veritatis tempora nulla facere placeat velit illum explicabo dicta enim ipsum. Vitae ducimus, ratione.</p>
</div>
</div>
<div class="masonry-item">
<div class="masonry-content">
<h3 class="masonry-title">Consequatur adipisci neque possimus quod ut quidem omnis numquam dolorum</h3>
<p class="masonry-description">Consectetur adipisicing elit. Sit enim ipsam mollitia repellat nemo, accusantium? Fugit id ipsam libero vitae quas perferendis, delectus a amet perspiciatis iusto. Quia, quam, culpa.</p>
</div>
</div>
<div class="masonry-item">
<div class="masonry-content">
<img src="https://picsum.photos/450/280?image=300" alt="Dummy Image">
<h3 class="masonry-title">Adipisci alias ullam est accusamus</h3>
<p class="masonry-description">Adipisci repellendus ratione laudantium nisi eaque voluptatem fuga quod hic, explicabo amet at laborum maiores ducimus et a vel quidem dolorem modi.</p>
</div>
</div>
<div class="masonry-item">
<div class="masonry-content">
<img src="https://picsum.photos/450/540?image=400" alt="Dummy Image">
<h3 class="masonry-title">Dolor sit amet, consectetur adipisicing elit</h3>
<p class="masonry-description">Vitae est numquam, dolore, ipsum tempora molestiae. Ut optio natus velit eaque tempora commodi dolor doloremque error quidem labore, incidunt odit est nobis numquam. Ullam quas minima, neque modi reiciendis consequuntur inventore!</p>
</div>
</div>
<div class="masonry-item">
<div class="masonry-content">
<img src="https://picsum.photos/450/380?image=500" alt="Dummy Image">
<h3 class="masonry-title">Veritatis...
CSS
body {
background-color: #cccccc;
color: #333333;
}
.masonry-wrapper {
padding: 1.5em;
max-width: 960px;
margin-right: auto;
margin-left: auto;
}
.masonry {
display: grid;
grid-template-columns: repeat(1, minmax(100px,1fr));
grid-gap: 10px;
grid-auto-rows: 0;
}
@media only screen and (max-width: 1023px) and (min-width: 768px) {
.masonry {
grid-template-columns: repeat(2, minmax(100px,1fr));
}
}
@media only screen and (min-width: 1024px) {
.masonry {
grid-template-columns: repeat(4, minmax(100px,1fr));
}
}
.masonry-item, .masonry-content {
border-radius: 5px;
overflow: hidden;
}
.masonry-item {
filter: drop-shadow(0px 2px 2px rgba(0, 0, 0, .3));
transition: filter .25s ease-in-out;
}
.masonry-item:hover {
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, .3));
}
.masonry-content {
overflow: hidden;
}
.masonry-item {
color: #111111;
background-color: #f9f9f9;
}
.masonry-title, .masonry-description {
margin: 0;
}
.masonry-title {
font-weight: 700;
font-size: 1.1rem;
padding: 1rem 1.5rem;
}
.masonry-description {
padding: 1.5rem;
font-size: .75rem;
border-top: 1px solid rgba(0, 0, 0, .05);
}
JavaScript
/**
* Set appropriate spanning to any masonry item
*
* Get different properties we already set for the masonry, calculate
* height or spanning for any cell of the masonry grid based on its
* content-wrapper's height, the (row) gap of the grid, and the size
* of the implicit row tracks.
*
* @param item Object A brick/tile/cell inside the masonry
* @link https://w3bits.com/css-grid-masonry/
*/
function resizeMasonryItem(item){
/* Get the grid object, its row-gap, and the size of its implicit rows */
var grid = document.getElementsByClassName('masonry')[0];
if( grid ) {
var rowGap = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-row-gap')),
rowHeight = parseInt(window.getComputedStyle(grid).getPropertyValue('grid-auto-rows')),
gridImagesAsContent = item.querySelector('img.masonry-content');
/*
* Spanning for any brick = S
* Grid's row-gap = G
* Size of grid's implicitly create row-track = R
* Height of item content = H
* Net height of the item = H1 = H + G
* Net height of the implicit row-track = T = G + R
* S = H1 / T
*/
var rowSpan = Math.ceil((item.querySelector('.masonry-content').getBoundingClientRect().height+rowGap)/(rowHeight+rowGap));
/* Set the spanning as calculated above (S) */
item.style.gridRowEnd = 'span '+rowSpan;
if(gridImagesAsContent) {
item.querySelector('img.masonry-content').style.height = item.getBoundingClientRect().height + "px";
}
}
}
/**
* Apply spanning to all the masonry items
*
* Loop through all the items and apply the spanning to them using
* `resizeMasonryItem()` function.
*
* @uses resizeMasonryItem
* @link https://w3bits.com/css-grid-masonry/
*/
function resizeAllMasonryItems(){
// Get all item class objects in one list
var allItems = document.querySelectorAll('.masonry-item');
/*
* Loop through the above list and execute the spanning function to
* each list-item (i.e. each masonry...