DEMO
FULL Screen DEMO
Masonry is not filling small gaps even if there is space.
Example :
Main Container width : 896px;
beside the first container with the orange background, there is a gap where Masonry could add one more container (Orange BG 2nd container), which is not happening. I'm not sure where I'm wrong. :-(
You need to maximize the window to see the issue.
JS :
jQuery(window).load(function() {
/* var container = document.querySelector('.masonry-container');
var msnry = new Masonry(container, {
itemSelector: '.itemMas',
columnWidth: 15,
gutter: 1,
isFitWidth: true
});
*/
$ = jQuery;
var $container = $('.masonry-container').masonry();
var msnry;
$container.imagesLoaded( function(){
msnry = new Masonry( $container[0], {
itemSelector : '.itemMas',
isAnimated: true,
isFitWidth: true
});
})
});
Masonry will not change the order of the elements in the document. It simply packs elements left-to-right as tightly as it can.
If you need to pack items by rearranging their layout, you want to use another library, such as Isotope (made by the same author). It features a bin-packing mode in which items can be rearranged to fit gaps.
Thanks for reporting this issue. This is how Masonry works. It may leave gaps. You should look at Packery, which was specifically designed to fill gaps.
Related
Here is the fiddle:
https://jsfiddle.net/qdhw0o3a/2/
I can't understand why all the items are being displayed on top of each other? Does it have something to do with the settings? I am just using the standard settings (as far as I can tell) which should produce behaviour similar to the website.
$('.grid').isotope({
itemSelector: '.grid-item',
layoutMode: 'masonry',
})
Try initiating the isotope after the window loads:
$(window).on('load', function() {
$('.grid').isotope({
itemSelector: '.grid-item',
layoutMode: 'masonry',
})
});
Note: Also, be on the lookout for Images Lazy-Loading in case your '.grid-item' contains images. This might interfere with isotope and make the elements come on top of each other.
you need to give the img and max-height and max-width.
see the updated Fiddle
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
$(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
screenshot 3
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:
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?
If 1. is yes => how do I fix the code so the images are not stacked on eachother anymore?
If 1. is no => how do I fix the code so the overlapping images and background bleed in screenshot 2 and 3 are gone?
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.
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.
I would like to remove the transition on the isotope items when the window resizes (so that the items do not animate their position or size), but still maintain the scaling/opacity/position transitions that happen when filtering/hiding/showing items.
Using the following code, however:
$container.isotope({transitionDuration: 0});
Removes both the window resize transition and the hide/show transition.
How can I just remove the window resize transition?
Thanks!
I can guarantee there's a better / more efficient way to do this, and I welcome any suggestions, but here's is how I've done it in the past:
Initialization:
// No transitions
$('.grid').isotope({
itemSelector: '.grid-item',
transitionDuration: 0,
isResizeBound: false
});
// Handle Resize
$(window).resize(function () {
$('.grid').isotope('layout');
});
Within the filter/click event:
// Add transition & filter
$('.grid').isotope({
transitionDuration: '0.4s',
filter: selector
});
// Remove transition
$('.grid').isotope({
transitionDuration: 0
});
The key is giving transitionDuration a value before the filter, and setting it back to 0 after the filter. How you do that shouldn't make a difference.
First of all, here is your fiddle,
url: https://jsfiddle.net/eugensunic/so1axnup/18/
Second
Here are the two pieces of code which are important in order to achieve such thing:
the property isResizeBound: false, should have the value false (by default it is true) so your elements no more have the transition applied on them.
Here is what the official documentation has to say on that:
Adjusts sizes and positions when window is resized. Enabled by default
isResizeBound: true
The other piece of code is important in order for your elements to STILL move when you trigger the resize event.
Here is an example:
$(window).resize(function(){
isotope.isotope('layout');
});
});
Once you start resizing your window, because of this code, the elements will start to re-position themselves ( you will have that "instant bootstrap effect" and no more "isotope animation effect").
If you decide not to use the "window resize code event", you won't have the element re-positioning occurring (it will sort of gain the effect of an absolute positioned item).
One more thing, be sure to use the V2 isotope js library.
url: https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.1/isotope.pkgd.min.js
EDIT as I'm exploring a little bit more, there is also this piece of code which allows you to get your effect
percentPosition: true,
masonry: {
columnWidth: '.grid-sizer'
}
see the codepen example: http://codepen.io/desandro/pen/mIkhq
As I can see, there is a lot more here, but playing with this three things mentioned will definitely get you where you want.
We can't figure our why there are large extra spaces in the Work section layout. Can anyone help?
http://new-had.herrmanneasyeditdemo.com/#work
To fix the loading issue with your div's showing before your images, you need to load your images using imagesLoaded. This prevents just the div's from showing before isotope is called. Since you are using isotope v1.56, not v2, it is included in that version of isotope. Change your custom.js (at line 107) isotope call to this:
var $container = $('#portfolio-container');
$container.imagesLoaded( function(){
$container.isotope({
resizable: false,
itemSelector : ".item",
masonry : {
columnWidth : 1,
gutterWidth: 1,
}
});
});
To fix your layout issue is more complicated since I'm not sure you can fit all your images in a seamless grid using isotope v1.56 and masonry ( most often you need to rearrange them for sizes to fit without white space). You would need to update to isotope v2 and load the packery layout option after isotope and then set your code up as so, for them to fit together.
var $container = $('#portfolio-container');
$container.imagesLoaded( function(){
$container.isotope({
layoutMode: 'packery',
itemSelector: '.item'
});
});
You will also have to change line 349:
$(window).resize(function(){
$('#portfolio-container').isotope('layout');
});
I know there are lots of answers to this on here, but none of them are working for me.
I'm trying to load images with a fixed width, but the images have varying heights.
I'm using the Jquery Masonry with imagesLoaded js but I still can't get it to work. If I set the width and height in css to a pixel size it works fine, but if I change height to auto it fails and all the images load the same height.
This is the javascript I'm using to initialise (I have tried many variations of this!)
var container = document.querySelector('#container');
var msnry;
// initialize Masonry after all images have loaded
imagesLoaded( container, function() {
msnry = new Masonry( container, {
// options
columnWidth: 390,
itemSelector: '.item'
} );
});
And this is the css
img {display:block; height:auto; width:390px;}
I've been hacking around with this for days now, somebody must know the answer!
Hopefully this will help a few people in the future.
The only thing I could get up with was to wait until the page was fully loaded for those heights to set and THEN grab those heights afterwards.
For this I used window.load. Maybe there is a better way but this worked for me.
$(window).load(function(){
$('.someDiv').each(function () {
var $this = $(this);
var someDivHeight = $this.height();
console.log(someDivHeight);
});
});