Forcing equal grid heights with JavaScript

Height has always been something of a problem in web design. There’s never been a very good way to have a grid list of items with equal height, not since the days of table based layouts.

Hard coding heights within CSS offered one solution but with Responsive Web Design and dynamic content it’s a dangerous and complicated task to pick a height for all instances.

One solution is to not be so hung up on everything appearing exactly aligned in the grid and accept the limitations. But alternatively you can turn to JavaScript to do it’s magic and apply height based exactly on what appears on screen.

With JavaScript you can determine not only the largest item but, as the code below does, it can do this for each individual row so that one super tall element doesn’t result in large amounts of whitespace in rows that do not require it.

The Code

To get the code working just apply the classname .item to the individual children of your grid, or edit the code however you see fit.

Note : This is the first working version of this code so there’s likely many ways to improve and refactor it. If you’ve got a suggestion of how let me know by commenting below.

 

function gridSize(){
  $storedHeight = 0;
  $lasttop = 0;
  $numrow = 0;
			
  $firstItemTop = $('.item:first-child').offset().top;
  $secondItemTop = $('.item:nth-child(2)').offset().top;
			
  if($firstItemTop == $secondItemTop){ // If items per row > 1
				
    $('.item').each(function(){

      $thistop = $(this).offset().top; // Top of current item
      $itemnum = $(this).index(); // Child number
      $thisheight = $(this).height(); // Height of current item

      if($lasttop == 0){ // First item of list
						
        $storedHeight = $thisheight;
						
      }else{

        if($lasttop == $thistop){ // If this item on same row as last item
							
          if($thisheight > $storedHeight){ // If height > stored height
            $storedHeight = $thisheight; // make stored height larger
          }
          $numrow = $numrow + 1;

        }else{ // Activates on item after the row we want to affect
							
          $until = ($itemnum - $numrow) -1;
          $(this).prevUntil(':nth-child(' + $until + ')').height($storedHeight); // adjust all items previous to this in same row
          $numrow = 0; // Reset row counter
          $storedHeight = $thisheight; // Reset height to this first item of row 
          $thistop = $(this).offset().top; // Reset thistop after adjustments to height
        }

        if($(this).is(':last-child')){ // If last item
          $(this).height($storedHeight); // Adjust the height of last item
        }
      }
      $lasttop = $thistop; // Update lasttop setting to this
    });
  }
}

gridSize(); // Run on load
		
$(window).smartresize(function(){
  $('.item').height('auto'); // Rest all heights
  gridSize();
});

The function also resets and runs again on resize of the browser window with the help of this smart resize code.

 

(function($,sr){

  // debouncing function from John Hann
  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
  var debounce = function (func, threshold, execAsap) {
      var timeout;

      return function debounced () {
          var obj = this, args = arguments;
          function delayed () {
              if (!execAsap)
                  func.apply(obj, args);
              timeout = null;
          };

          if (timeout)
              clearTimeout(timeout);
          else if (execAsap)
              func.apply(obj, args);

          timeout = setTimeout(delayed, threshold || 100);
      };
  }
  // smartresize 
  jQuery.fn[sr] = function(fn){  return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };

})(jQuery,'smartresize');

We'd love to hear from you!

If you think Bronco has the skills to take your business forward then what are you waiting for?

Get in Touch Today!

Discussion

Add a Comment