JSFiddle - React, Tailwind, and code Playground
by AldoRomo88
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.0/masonry.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<button @click="add">
Add
</button>
<div class="grid">
<div v-for="item in items" @click="toggle(item)" class="grid-item" :class="[{'grid-item--gigante':item.isGigante}, item.size]"></div>
</div>
</div>
CSS
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- grid ---- */
.grid {
background: #EEE;
max-width: 1200px;
}
/* clearfix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- grid-item ---- */
.grid-item {
width: 50px;
height: 50px;
float: left;
background: #D26;
border: 2px solid #333;
border-color: hsla(0, 0%, 0%, 0.5);
border-radius: 5px;
}
.grid-item--width2 {
width: 100px;
}
.grid-item--width3 {
width: 150px;
}
.grid-item--width4 {
width: 200px;
}
.grid-item--height2 {
height: 75px;
}
.grid-item--height3 {
height: 100px;
}
.grid-item--height4 {
height: 150px;
}
.grid-item--gigante {
width: 250px;
height: 250px;
z-index: 2;
/* above other items */
}
.grid-item:hover {
background: #A2C;
border-color: white;
cursor: pointer;
}
JavaScript
let widthClasses = ['', 'grid-item--width2', 'grid-item--width3', 'grid-item--width4'];
let heightClasses = ['', 'grid-item--height2', 'grid-item--height3', 'grid-item--height4'];
let data = [];
for (let x = 0; x < 10; x++) {
data.push({
isGigante: false,
size: '' + widthClasses[Math.floor(Math.random() * widthClasses.length)] + ' ' + heightClasses[Math.floor(Math.random() * heightClasses.length)]
})
}
new Vue({
el: '#app',
data: function() {
return {
items: data,
msnry: null,
}
},
mounted() {
let grid = document.querySelector('.grid');
this.msnry = new Masonry(grid, {
columnWidth: 25
});
},
methods: {
toggle(item) {
item.isGigante = !item.isGigante;
Vue.nextTick(() => {
// DOM updated
this.msnry.layout();
});
},
add() {
this.items.push({
isGigante: false,
size: '' + widthClasses[Math.floor(Math.random() * widthClasses.length)] + ' ' + heightClasses[Math.floor(Math.random() * heightClasses.length)]
});
Vue.nextTick(() => {
// DOM updated
this.msnry.reloadItems();
this.msnry.layout();
});
}
}
})