Pinterest Layout Plugin - Demo

HTML
<div class="cards"> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/65/33/85/6533859c383845b498d81990c4be2a41.jpg" /> </div> <div class="card-info"> Low-poly illustrations </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/19/dc/3d/19dc3d3f392a57378c55c32e3ef7574e.jpg" /> </div> <div class="card-info"> Burger Bits by cronobreaker.devi... on @deviantART </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/5c/dd/72/5cdd72b452abf457e85ec9ea38aa6559.jpg" /> </div> <div class="card-info"> Da' Monk Photo by Mnk Crew </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/89/df/1c/89df1ceeb79793465779a273794faa10.jpg" /> </div> <div class="card-info"> vector animals <br> Photo by Çetin Can Karaduman on Behance </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/f8/e7/bf/f8e7bfc4e7523e1d050fd12e2141eb48.jpg" /> </div> <div class="card-info"> Diet Zombie Pop by cronobreaker.devi... on @deviantART </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/0a/ec/7b/0aec7ba66f3970edbeed34168ea7e776.jpg" /> </div> <div class="card-info"> Vectors Assemble <br> Photo by William Teal on Behance </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/8f/de/a6/8fdea6e709e1dbf66aa5f031c0e187fc.jpg" /> </div> <div class="card-info"> Camila 2 - Urban Arts by Cristiano </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/c2/7f/4c/c27f4ce431471238a8ac08de609a3e24.jpg" /> </div> <div class="card-info"> BMO v2.0 by shoden23.devianta... on @deviantART </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/2a/04/0f/2a040f6fd57319510e6c7a027795cb1d.jpg" /> </div> <div class="card-info"> FORCE AWAKENS DEADPOOL-vector <br> Photo by Orlando Arocena on Behance </div> </div> <div class="card"> <div class="card-image"> <img src="https://s-media-cache-ak0.pinimg.com/564x/e7/66/c2/e766c2d243ed4b6962d71ba8b48ffddf.jpg" /> </div> <div class="card-info"> Breaking Bad by Guillaume </div> </div> </div>
SCSS
* { box-sizing: border-box; } body { color: #212121; font-size: 13px; font-family: 'Helvetica Neue', sans-serif; background: #ECEFF1; padding: 2em; } .cards { opacity: 0; margin: auto; &--loaded { opacity: 1; } } .card { backface-visibility: hidden; background: #fff; box-shadow: 1px 1px 2px rgba(0,0,0,0.3); border-radius: 4px; display: inline-block; margin-bottom: 10px; margin-right: 10px; min-height: 100px; opacity: 0; transition: all 300ms ease-in-out; transform-origin: 50% 50% 0; vertical-align: top; width: 150px; &--loaded { opacity: 1; } .card-image { img { width: 100%; border-radius: 4px 4px 0 0; } } .card-info { padding: 10px 16px; } }
JAVASCRIPT
(function(exports) { 'use strict'; function PinterestGrid(options) { this.settings = Object.assign({ delay: 100, shorterFirst: true, gutter: 6 }, options); this.loaded = false; this.transform = _getTransformProperty(); this.$container = options.container instanceof Node ? options.container : document.querySelector(options.container); if (!this.$container) { return false; } this.$itemCollection = options.item instanceof NodeList ? options.item : this.$container.querySelectorAll(options.item); if (!this.$itemCollection || this.$itemCollection.length === 0) { return false; } if (!this.loaded) { return this.init(); } } PinterestGrid.prototype.init = function() { this.loaded = true; var gutter = parseInt(this.settings.gutter); var callback = this.settings.callback; this.$container.style.width = ''; var containerWidth = this.$container.getBoundingClientRect().width; var firstChildWidth = this.$itemCollection[0].getBoundingClientRect().width + gutter; var cols = Math.max(Math.floor((containerWidth - gutter) / firstChildWidth), 1); containerWidth = (firstChildWidth * cols + gutter) + 'px'; this.$container.style.width = containerWidth; this.$container.style.position = 'relative'; var itemsGutter = []; var itemsPosX = []; for (var g = 0; g < cols; g++) { itemsPosX.push(g * firstChildWidth + gutter); itemsGutter.push(gutter); } Array.from(this.$itemCollection).forEach(function (item, i) { if (this.settings.shorterFirst) { var itemIndex = itemsGutter.slice(0).sort(function(a, b) { return a - b }).shift(); itemIndex = itemsGutter.indexOf(itemIndex); } else { var itemIndex = i % cols; } var posX = itemsPosX[itemIndex]; var posY = itemsGutter[itemIndex]; item.style.position = 'absolute'; item.style.webkitBackfaceVisibility = item.style.backfaceVisibility = 'hidden'; item.style[this.transform] = 'translate3D(' + posX + 'px,' + posY + 'px, 0)'; itemsGutter[itemIndex] += item.getBoundingClientRect().height + gutter; if (!/loaded/.test(item.className)) { setTimeout(function() { item.classList.add(item.className.split(' ')[0] + '--loaded'); }, (parseInt(this.settings.delay) * i)); } }.bind(this)); var containerHeight = itemsGutter.slice(0).sort(function(a, b) { return a - b }).pop(); this.$container.style.height = containerHeight + 'px'; if (!/loaded/.test(this.$container.className)) { this.$container.classList.add(this.$container.className.split(' ')[0] + '--loaded'); } if (typeof callback === 'function') { callback(this.$itemCollection); } } function _getTransformProperty() { var style = document.createElement('div').style; var transform; var vendorProp; if (undefined !== style[vendorProp = 'webkitTransform']) { transform = vendorProp; } if (undefined !== style[vendorProp = 'msTransform']) { transform = vendorProp; } if (undefined !== style[vendorProp = 'transform']) { transform = vendorProp; } return transform; } // AMD if (typeof define === 'function' && define.amd) { define(function() { return PinterestGrid }); } // CommonJS else if (typeof module !== 'undefined' && module.exports) { module.exports = PinterestGrid; } // Global Property else { exports.PinterestGrid = PinterestGrid; } }(this)); (function() { var grid = new PinterestGrid({ delay: 100, container: '.cards', item: '.card', gutter: 10 }); window.addEventListener('resize', function() { grid.init(); }); Array.from(document.querySelectorAll('.card img')).forEach(function(item) { console.log(item); item.addEventListener('load', function() { grid.init(); item.removeEventListener('load'); }, false); }); })();
Expand for more options Login