JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://masonry.desandro.com/jquery.masonry.min.js"></script>
<div id="holder">
     
         
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
 
 
</div>

CSS

body {
    padding: 1%; margin: 0;
    background: #f9f9f9;
}
 
.box {
    height: 100%;
    float: left;
    background: #fff;
    overflow: hidden;
    border-radius: 4px;
    box-shadow: 0px 1px 3px rgba(0,0,0,0.2);
}
 
.wrapper {
    display: block;
    width: 97%;
    padding: 1.5% 1.5% 0 1.5%; 
    height: 350px;
    float: left;
}
 
.single .box {
    width: 100%;
}
 
a {
    border: 0;
    text-decoration: none;
}
 
/* 2 IMAGES PER WRAPPER */
.left-big .box:last-child { width: 35%; }
.left-small .box, .left-big .box { width: 65%; }
.left-small .box:first-child { margin: 0 1.5% 0 0; width: 33.5%; }
.left-big .box:first-child { margin: 0 1.5% 0 0; width: 63.5%; }
 
/* 3 IMAGES PER WRAPPER */
.big-middle .box:nth-child(2) { width: 47%; margin: 0 1.5%; }
.big-middle .box:first-child, .big-middle .box:last-child { width: 25%; }
.small-middle .box:nth-child(2) { margin: 0 1.5%; width: 22%; }
.small-middle .box:first-child, .small-middle .box:last-child { width: 37.5%; }
 
/* 4 IMAGES PER WRAPPER */
 
.middle-two-rows .box, .right-two-rows .box  { width: 25%; }
 
.right-two-rows .box:nth-of-type(2) {
    margin: 0 0 0 1.5%;
    width: 23.5%;
}
 
.middle {
    float: left;
    width: 47%;
    height: 100%;
    margin: 0 1.5%;
}
 
.middle .box {
    height: 165px;
    width: 100%;
    clear: both;
    margin: 0;
}
 
.right-two-rows .middle .box:last-child {
    margin: 0;
}
.right-two-rows .middle {
    margin: 0 0 0 1.5%;
    width: 48.5%;
}
 
.right-two-rows .middle .box {
    width: 100%;
}
 
.middle .box:first-child {
    margin: 0 0 20px 0;
}
 
 
/* 5 IMAGES PER WRAPPER */
 
.four-block .box { width: 48.5%; margin: 0 1.5% 0 0; }
 
.block {
    width: 50%;
    height: 100%;
    float: left;
}
.block .box {
    margin: 0;
    height: 165px;
    margin: 0 3% 0 0;
}
 
.block .box:nth-of-type(3), .block .box:nth-of-type(4) { margin-top: 20px; }
.block .box:nth-child(2), .block .box:nth-child(4) { margin-right: 0; }

JavaScript

$(document).ready(function() {
 
    // Some Variables
    var noBoxes = $('#holder .box');
    var randNumber, prev;
    var i = 0;
     
    //Run a while loop to go through all the boxes
    while(i < noBoxes.length) {
         
        // ensure the random number is different every time
        do {
            randNumber = Math.floor(Math.random() * (6 - 2) + 2); // the random number
        } while(randNumber === prev);
        prev = randNumber;
         
        // If i is 0, it's the first set of boxes, so wrap the first 5 in a wrapper (the header)
        if(i == 0) {
            noBoxes.slice(0, 5).wrapAll("<div class='wrapper'></div>");
            i+=5;
        }
        // Otherwise..
        else {
            // If i is 5 it's the second set of boxes, so ensure that the random number isn't 5.
            if(i == 5) {
                newRand = Math.floor(Math.random() * (5 - 2) + 2);  
                noBoxes.slice(i, i+newRand).wrapAll("<div class='wrapper'></div>");
                i+=newRand;
            }
            // Then just run the loop normally 
            else {
                noBoxes.slice(i, i+randNumber).wrapAll("<div class='wrapper'></div>");
                i+=randNumber;
            }
             
        }
    }
     
    // Since the wrappers have been made, run this function for each
    $('.wrapper').each(function() {
     
        // Get the number of children in this wrapper
        var noChildren = $(this).children('.box').length;
         
        // An array of the classes we're going to use
        var cssClass = [
            'single', // 1 IMAGE PER WRAPPER
            'left-big', 'left-small', // 2 IMAGES PER WRAPPER
            'small-middle', 'big-middle', // 3 IMAGES PER WRAPPER
            'middle-two-rows', 'right-two-rows', // 4 IMAGES PER WRAPPER
            'four-block' // 4 IMAGES PER WRAPPER
        ];
         
        // If there is only 1 child then add this class
        if(noChildren == 1) {
        ...