1

I am trying to recreate the masonry blog view from Unify in Rails 4. http://htmlstream.com/preview/unify-v1.8/blog_masonry_3col.html

I bought the theme and included the latest imagesLoaded and Masonry files within my application (using bower-rails).

  • Masonry PACKAGED v3.3.2
  • imagesLoaded PACKAGED v3.2.0

When using the with the theme supplied js file all images are stacked on top of each other.

screenshot 1 stacked on eachother

$(document).ready(function(){
    var $container = $('.grid-boxes');

    var gutter = 30;
    var min_width = 300;
    $container.imagesLoaded( function(){
        $container.masonry({
            itemSelector : '.grid-boxes-in',
            gutterWidth: gutter,
            isAnimated: true,
              columnWidth: function( containerWidth ) {
                var box_width = (((containerWidth - 2*gutter)/3) | 0) ;

                if (box_width < min_width) {
                    box_width = (((containerWidth - gutter)/2) | 0);
                }

                if (box_width < min_width) {
                    box_width = containerWidth;
                }

                $('.grid-boxes-in').width(box_width);

                return box_width;
              }
        });
    });
});

See this js fiddle: http://jsfiddle.net/sdynfq83/

I noticed following things:

  • Resizing the window or refreshing does not correct the issue so I figured out it is not an images loaded error. This took me a long time to figure this out.
  • My html code seems alright since I have the same problems if I copy the HTML code from the theme itself and include the same JS and CSS files.
  • the ".grid-boxes-quote" boxes don't have the same width as the other grid boxes. Which is strange because they should all be the same since all boxes have the ".grid-boxes-in" class. https://jsfiddle.net/sdynfq83/embedded/result/

When removing the columnWidth code and replacing it by a fixed number (300) + adding width to the grid-boxes-in then it seems to work. This is not what I want since the images sizes are not correct anymore.

css

.blog_masonry_3col .grid-boxes-in {
    padding: 0;
    margin-bottom: 30px;
    border: solid 1px #eee;
    /* added width */
    width: 300px;

}

js

$(document).ready(function(){
    var $container = $('.grid-boxes');

    var gutter = 30;
    var min_width = 300;
    $container.imagesLoaded( function(){
        $container.masonry({
            itemSelector : '.grid-boxes-in',
            gutterWidth: gutter,
            isAnimated: true,
              /*columnWidth: function( containerWidth ) {
                var box_width = (((containerWidth - 2*gutter)/3) | 0) ;

                if (box_width < min_width) {
                    box_width = (((containerWidth - gutter)/2) | 0);
                }

                if (box_width < min_width) {
                    box_width = containerWidth;
                }

                $('.grid-boxes-in').width(box_width);

                return box_width;
              }*/
            columnWidth: 300
        });
    });
});

js fiddle: http://jsfiddle.net/8c0r06a6/2/

The theme itself supplies an older version of masonry. In which the code seems to work. The images do keep overlapping (this can be fixed by resizing or refreshing the window).

Screenshot 2 overlapping images screenshot 3 enter image description here

I however want to update to the latest version of masonry and images loaded so I can keep using bower to easily update those files. I am also hoping that using the latest version of everything fixes the overlapping images in screenshot 2. I have a working JS fiddle below with the old code.

/**
 * jQuery Masonry v2.1.05
 * A dynamic layout plugin for jQuery
 * The flip-side of CSS Floats
 * http://masonry.desandro.com
 *
 * Licensed under the MIT license.

http://jsfiddle.net/ytLf3bue/1/

Summarized I have following questions, please bear in mind that I am a beginning hobby coder and I do not have a lot of JS experience:

  1. Is it a smart idea to always use the latest version of the Masonry and ImagesLoaded code or should I just stick with the supplied files?
  2. If 1. is yes => how do I fix the code so the images are not stacked on eachother anymore?
  3. If 1. is no => how do I fix the code so the overlapping images and background bleed in screenshot 2 and 3 are gone?
Christoph
  • 1,347
  • 2
  • 19
  • 36

2 Answers2

1

Anytime you are dealing with masonry, instead of using:

$(document).ready(function(){ ... go masonry ... }

use:

$(window).load(function(){ ... go masonry ... }

http://jsfiddle.net/sdynfq83/2/

$(document).ready triggers as soon as the DOM is completely loaded. That does not include loading of resources like images. Masonry calculates the absolute positioning of images based on their widths and heights. If it runs before the actual image is loaded it sees the image tag as an element with zero width and height. There for it only offsets for the gutter between and the images end up stacked.

$(window).load triggers once all page resources have finished loading. This allows Masonry to get the correct dimensions of all objects before it tries to place them.

Gregg Duncan
  • 2,635
  • 1
  • 14
  • 20
  • It seems take in your fiddle the widths are still not correct. It just takes the entire width of its parent container. If I get the correct output it should be a grid like the other fiddles. Also I am using the imagesLoaded plugin (recommended by Masonry) for detecting if images are loaded. – Christoph Nov 10 '15 at 07:41
  • Part of the problem is that your masonry selector is a div. And since you have not set a width or declared it as an inline block then it's calculated width is naturally 100% of it's container. – Gregg Duncan Nov 10 '15 at 16:26
1

David Desandro answered me himself.

$(document).ready( function() {
  // init Masonry after all images have loaded
  var $grid = $('.grid').imagesLoaded( function() {
    $grid.masonry({
      itemSelector: '.grid-item',
      percentPosition: true,
      gutter: 20,
      columnWidth: '.grid-sizer'
    });
  });

});

In Masonry v3, columnWidth no longer accepts a function. Instead, use element sizing for responsive layouts.

Here's a demo http://codepen.io/desandro/pen/f3451d70f80c35812b33956785ee152c/

This fixes the issue.

Christoph
  • 1,347
  • 2
  • 19
  • 36