JSFiddle - React, Tailwind, and code Playground

HTML

<span id="heightholder"></span>
<div id="grid_container_holder">
    <div id="grid_container">
        <div class="grid-item">
            <div>1</div>
        </div>
        <div class="grid-item">
            <div>1<br><br></div>
        </div>
        <div class="grid-item">
            <div>1</div>
        </div>
        <div class="grid-item">
            <div>1<br>2<br>3<br>4</div>
        </div>
    
    </div>
    
    <div>
        This is the footer section to show below the gallery
    </div>
</div>

CSS

#grid_container{
  position:relative;
	width:100%;
	margin:0px auto;
  background: #ff0;
}
.grid-item{
	position:absolute;
	width: 30%;
	border: #000 1px solid;
  opacity: 0.3;
}
.grid-item:nth-child(2n+0) {
	background: #FFDC64;
}
.grid-item:nth-child(2n+1) {
    background: #FEC910;
}
#grid_container .grid-item > div{ padding: 20px; font-size: 27px; color:#D9A800; }

JavaScript

function renderGrid(){
var blocks = document.getElementById("grid_container").children;
var pad = 0, cols = 3, newleft
var newtop = 0
var max_height = blocks.length ? blocks[0].offsetHeight : 0;
  
	for(var i = 1; i < blocks.length; i++){
		if (i % cols == 0) {
			newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight) + pad;     
		  blocks[i].style.top = newtop+"px";
		  max_height = Math.max(max_height, newtop + blocks[i].offsetHeight);
		} else {
			if(blocks[i-cols]){
				newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight) + pad;
				blocks[i].style.top = newtop+"px";
				max_height = Math.max(max_height, newtop + blocks[i-cols].offsetHeight);
			}
			newleft = (blocks[i-1].offsetLeft + blocks[i-1].offsetWidth) + pad;
			blocks[i].style.left = newleft+"px";
			max_height = Math.max(max_height, newtop + blocks[i-1].offsetHeight);
		}
  }
    $('#grid_container').css('height', max_height);
}
window.addEventListener("load", renderGrid, false);
window.addEventListener("resize", renderGrid, false);