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) {
...