3

I have a simple masonry layout. And need to change elements size and position on click.

Here is a jsfiddle: http://jsfiddle.net/664cV/12/ and the code:

JS

$(function(){
    $('#container').isotope({
        itemSelector: '.box'
    });

    $('.box').click(function(){
        $('.box').width(100).height(100);
        $(this).width(300).height(300);

        $('#container').isotope('reLayout');
    });
});​

CSS

#container {
    width: 400px;
}

.box {
    font-size: 28px;
    width: 100px;
    height: 100px;
}

/* omitted color classes */

HTML

<div id="container">
    <div class="box red">1</div>
    <div class="box blue">2</div>
    <div class="box green">3</div>
    <div class="box yellow">4</div>
    <div class="box black">5</div>
</div>​

The problem is that it isn't working correctly for element number 1 and number 3 (see images)

Element 1 clicked (solved: see answer)

Error 1

Element 3 clicked

Error 2

What am I doing wrong?

Community
  • 1
  • 1
Luca
  • 1,098
  • 1
  • 12
  • 19
  • 1
    So.... your JSfiddle is useless to us, it doesn't have the `Isotope()` plugin with it? (I assume it's a plugin...) – Barrie Reader Oct 19 '12 at 12:21
  • See http://jsfiddle.net/MTxXZ/1/ explaining the usual problem with multi-column elements http://stackoverflow.com/a/11701171/963514. Your fiddle does not work, but your screenshots show the issue. If you have non-column coherent or multi-column items, on various browser window sizes, you may have empty spaces. – Systembolaget Oct 19 '12 at 12:47
  • I will update the fiddle asap. – Luca Oct 19 '12 at 12:55
  • @Neurofluxation I replaced github external reference with the one in the official plugin page. Now it should work. – Luca Oct 19 '12 at 13:45
  • @Systembolaget so the short answer is: "it just works this way"? – Luca Oct 19 '12 at 13:55
  • Yes. It is always a combination of browser window size, element order in the DOM, element width and column width for that matter that need to be considered. Otherwise, you'd need a bin-packing algorithm that always resorts elements, disrespective of their order in the DOM, to always create flush layouts with multiple element sizes cross-column. If you have many small elements of one and two column width, as in the Isotope documentation, your chance of an "always flush" fit is high. – Systembolaget Oct 19 '12 at 14:31
  • @Systembolaget: Can you explain what masonry shares with bin-packing? In my answer you can see it's some sort of random order best-fit 1d bin-packing. Maybe you mean a kd-tree packing algorithm? – Micromega Oct 19 '12 at 15:06
  • Masonry unfortunately shares nothing with bin packing, that's why the user can't get close to what he wants. Pinterest uses a column based aproach also. The user wants a best fit approach that works with elements spanning multiple columns. However, for so-called NP-hard problems, he could try to port MATLAB or FORTRAN code implementing a genetic algorithm - or first look into simpler top-left solutions like http://codeincomplete.com/posts/2011/5/7/bin_packing/ and work from there. Easiest solution with Masonry/Isotope - keep items small or fluid with multi-column approaches and snug fit. – Systembolaget Oct 19 '12 at 15:51
  • @Systembolaget thanks for the bin-packing link. Now I think the most affordable solution would be an implementation of custom isotope layout http://isotope.metafizzy.co/docs/extending-isotope.html#custom_layout_modes using bin-packaging. – Luca Oct 19 '12 at 20:09

3 Answers3

3

You need to set the masonry first item width so that, once re-sized, isotope will remember this settings instead of the new first item width keeping the grid consistent.

Sadly, item number three still leaves an empty space, but I think that is isotope's standard behavior since it puts the fourth item up to the first, free, row, in that case row number one.

masonry: {
    columnWidth: 100
}

In fact, if you click on the box number 7, it leave an empty space as well. It would be nice to find a solution to that default behavior too.

<div class="box red">6</div>
<div class="box blue">7</div>
<div class="box green">8</div>
<div class="box yellow">9</div>
<div class="box black">10</div>
caruso_g
  • 404
  • 6
  • 16
  • The "masonry first item width" link has moved with version 2 of the docs and is now [here](http://isotope.metafizzy.co/v2/faq.html#the-first-item-breaks-the-grid) – Tomas Mulder Mar 15 '17 at 17:47
0

masonry and isotope maximize only columns. You can find an explanation from the wookmark jquery plugin. When you want to maximize columns and rows you need something else.

  1. http://www.quora.com/Pinterest/What-technology-is-used-to-generate-pinterest-coms-absolute-div-stacking-layout
  2. http://www.benholland.me/javascript/how-to-build-a-site-that-works-like-pinterest/
Micromega
  • 12,486
  • 7
  • 35
  • 72
0

I just ran into this problem myself and fixed it by adding an empty div at the top of the container with the same selector as my masonry items, then added the css:

.grid-item:first-child {
    width: 1px;
    height: 0;
    padding: 0;
}

If you're wondering if this will result in your first item being shifted right by a pixel, the answer is no. I'm guessing this is because the height is 0, so it takes up no space. I wish this didn't involve adding unnecessary HTML, but it seems to work pretty well.

gspiker
  • 1
  • 1