Dynamic width content grid with jQuery and Isotope

Ernest Marcinko jQuery, Tutorials 2 Comments

This small code snippet will allow you to create a content grid, which fits it's container width at all times by calculating the optimal width of the columns. It's highly responsive, works with any (sane) container width.
It's just a small code snippet, you can easily change it. I decided to use jQuery as many of you use it by default, and the javascript enthusiasts will probably port it for their needs in 5 minutes.

See the Pen Dynamic Content Grids with jQuery and Isotope by Ernest Marcinko (@wpdreams) on CodePen.

HTML

As I said before, it's merely a demonstration so nothing is strict except for the item sizes – all of them must be the same. I will most likely make an update later on to support dynamic item heights.

<div class='jdg-container'>
   <!-- First item -->
   <div class='jdg-item'>
     <img src='https://i.imgur.com/eXZxk5x.png' />
     <p>Don't eat your phone</p>
   </div>   

   <!-- Second item -->
   <div class='jdg-item'>
     <img src='https://i.imgur.com/3DO53fz.png' />
     <p>This mouse is expensive</p>
   </div>  

   <!-- Third item, etc..-->
</div>

CSS

Mostly colors and font sizes, however the items must be floating to fit properly.

.jdg-container {
  width: 610px;
  height: auto;
  background: transparent;
  boder-radius: 2px;
  overflow: hidden;
  box-sizing: content-box;
}

.jdg-item { 
  width: 200px;
  height: 180px;
  margin: 2px;
  padding: 0 0 10px;
  position: relative;
  background: #efefef;
  border-bottom: 4px solid #657581;
}

.jdg-item p {
  margin: 0;
  font-size: 13px;
  margin: 2px 6px;
  font-weight: 600;
  color: #205770;
}

.jdg-item img {
  width: 100%;
  height: auto;
  margin: 0;
  padding: 0;
  box-sizing: content-box;
}

Javascript

The jQuery plugin code is somewhat longer, but it's easily understandable.

// The dynamicGrid plugin code starts here
(function ($) {
    var methods = {

        init: function (options, elem) {
        	var $this = this;

        	this.elem = elem;
        	this.$elem = $(elem);
           this.o = $.extend({
             "isotopeArgs": {
               "itemSelector": ".jdg-item",
               "layoutMode": "masonry"
             },
             "width": 300,
             "height": 150,
             "itemsSelector": ".jdg-item"
           }, options); 
           var t = null;  
           $this.isotopeInstance = new Isotope(this.elem, this.o.isotopeArgs);
        	$(window).on('resize', function(){
              t = setTimeout(function(){
              	$this.resizeColumns(); 
                $this.isotopeInstance.arrange();
              });
        	});
        },
      
      	resizeColumns: function ( ) {
          	var $items = $(this.o.itemsSelector, this.elem);
            var containerWidth = parseFloat($(this.elem).innerWidth());
            var realColumnCount = containerWidth / this.o.width;
            var floorColumnCount = Math.floor(realColumnCount);
            if (floorColumnCount <= 0)
                floorColumnCount = 1;
            /*if ((realColumnCount - floorColumnCount) > 0.8)
             floorColumnCount++;*/
            if (Math.abs(containerWidth / floorColumnCount - this.o.width) >
                Math.abs(containerWidth / (floorColumnCount + 1) - this.o.width)) {
                ++floorColumnCount;
            }

            var newItemW = Math.floor(containerWidth) / floorColumnCount - $items.outerWidth(true) + $items.innerWidth();
            var newItemH = (newItemW / this.o.width) * this.o.height;

            $items.css({
                width: Math.floor(newItemW),
                height: Math.floor(newItemH)
            });
      	}
    };
    
    if (typeof Object.create !== 'function') {
        Object.create = function (o) {
            function F() {
            }

            F.prototype = o;
            return new F();
        };
    }

    // Create a plugin based on a defined object
    $.plugin = function (name, object) {
        $.fn[name] = function (options) {
            return this.each(function () {
                if (!$.data(this, name)) {
                    $.data(this, name, Object.create(object).init(
                        options, this));
                }
            });
        };
    };

    $.plugin('dynamicGrid', methods);
})(jQuery);
// The dynamicGrid plugin code ends here

Usage

A classic plugin initialization.

$(document).ready(function(){
  $(".jdg-container").dynamicGrid({
    "isotopeArgs": {},
    "width": 200,
    "height": 180,
    "itemsSelector": ".jdg-item"
  });
});

The isotopeArgs variable expects an object with the arguments for the Isotope instance. You can read abou the isotope config on it's website.

Ernest Marcinko

WordPress developer, javascript enthusiast, photoshop clicker and the founder of wp-dreams.com

Comments 2

  1. Sofia

    Very useful article for the people like me. It’s really a worthy post with great explanation on code snippet’s and how can we edit easily. Thanks a lot for sharing this.

Leave a Reply

Your email address will not be published. Required fields are marked *

Human test *