Menu icon Foundation
Integrate jquery Masonry (or Isotope) with Foundation

Hi guys,

I was wondering if anyone is using Metafizzy's Masonry or Isotope with foundation, and how they integrated the width parts.

Basically I want foundation's columns to handle the horizontal spacing and Masonry to handle the (vertical) gaps created by items with varying heights.

I know people have done this before. I've tried implementing it before, but was missing something, which meant no responsive layouts that looked the way I wanted it to.

Anyway, I'm gonna start on my local wordpress install soon to accomplish the pinterest like look for my blog posts and would like your input. (The blog items will probably be small-12 medium-6 large-4 columns.)

All tips are welcome! (I'm only needing the masonry functionality atm, but if you can suggest a solution with Isotope that would be good too. I haven't tried Isotope 2 yet, but I remember seeing it was good for responsive layouts?)

Thanks!

ps: can we get a report button on the forum? Right now there are a couple of usernames which are doing some massive spamming and it sucks balls.

masonryisotopevarying height

Hi guys,

I was wondering if anyone is using Metafizzy's Masonry or Isotope with foundation, and how they integrated the width parts.

Basically I want foundation's columns to handle the horizontal spacing and Masonry to handle the (vertical) gaps created by items with varying heights.

I know people have done this before. I've tried implementing it before, but was missing something, which meant no responsive layouts that looked the way I wanted it to.

Anyway, I'm gonna start on my local wordpress install soon to accomplish the pinterest like look for my blog posts and would like your input. (The blog items will probably be small-12 medium-6 large-4 columns.)

All tips are welcome! (I'm only needing the masonry functionality atm, but if you can suggest a solution with Isotope that would be good too. I haven't tried Isotope 2 yet, but I remember seeing it was good for responsive layouts?)

Thanks!

ps: can we get a report button on the forum? Right now there are a couple of usernames which are doing some massive spamming and it sucks balls.

This post has been closed. No new replies can be added.

Jens Geiling over 5 years ago

I've had good experiences with the Wookmark jquery plugin (http://www.wookmark.com/jquery-plugin) for a grid layout with dynamic heights. It's also smaller than Masonry.
In general i think the simplest method is to make a foundation container and let the plugin do the rest of the (responsive) work.

Some other layout plugins:
- http://packery.metafizzy.co
- http://mcpants.github.io/jquery.shapeshift/
- http://suprb.com/apps/nested/
- http://jonobr1.github.io/stalactite/
- http://yconst.com/web/freetile/

Loc over 5 years ago

Try the the code below to see if it works for you. This will allow "masonry" to handle vertical spacing and allow "foundation" to handle horizontal spacing depending on screen resolution.

<div class="row">
                <div class="medium-12 columns">
                    <div id="container" class="js-masonry" data-masonry-options='{ "itemSelector": ".item" }'>
                        <div class="row">
                            <div class="small-12 medium-6 large-4 columns item">
                                <img src="images/image1.jpg" alt="Image">
                            </div>
                            <div class="small-12 medium-6 large-4 columns item">
                                <img src="images/image2.jpg" alt="Image">
                            </div>
                            <div class="small-12 medium-6 large-4 columns item">
                                <img src="images/image3.jpg" alt="Image">
                            </div>
                            <div class="small-12 medium-6 large-4 columns item">
                                <img src="images/image4.jpg" alt="Image">
                            </div>
                            <div class="small-12 medium-6 large-4 columns item">
                                <img src="images/image5.jpg" alt="Image">
                            </div>
                            <div class="small-12 medium-6 large-4 columns item">
                                <img src="images/image6.jpg" alt="Image">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
.item {
  margin-bottom: 0.5rem;
}

Ercan Murat KISACA over 5 years ago

I used Isotope in my latest project.

The html structure

<ul class="inline-list portfolio-list" id="filters">
<li><a href="#" class="selected" data-filter="*">All</a></li>
<li><a href="#" data-filter=".html">HTML5</a></li>
<li><a href="#" data-filter=".java">Java</a></li>
<li><a href="#" data-filter=".php">PHP</a></li>
</ul>
<div id="container" class="text-center">
  <div class="item html"><a href="#"><img src="assets/img/image.jpg"><h6>HTML5</h6></a></div>
  <div class="item java"><a href="#"><img src="assets/img/image.jpg"><h6>Java</h6></a></div>
  <div class="item php"><a href="#"><img src="assets/img/image.jpg"><h6>PHP</h6></a></div>
</div>

The script code at the end of the page before closing body tag

<script>
$(window).load(function(){


var $container = $('#container');
// initialize isotope
$container.isotope({

  itemSelector : '.item',
  //layoutMode : 'fitRows'
  masonry: {
    columnWidth: 194
  }
  // options...
});

// filter items when filter link is clicked
$('#filters a').click(function(){
  var selector = $(this).attr('data-filter');
  $container.isotope({ filter: selector });
  return false;
});

// set selected menu items
   var $optionSets = $('.inline-list'),
       $optionLinks = $optionSets.find('a');

       $optionLinks.click(function(){
          var $this = $(this);
    // don't proceed if already selected
    if ( $this.hasClass('selected') ) {
        return false;
    }
   var $optionSet = $this.parents('.inline-list');
   $optionSet.find('.selected').removeClass('selected');
   $this.addClass('selected'); 
});

});

</script> 

Then some CSS of course

/**** Isotope Filtering ****/

.isotope-item {
  z-index: 2;
}

.isotope-hidden.isotope-item {
  pointer-events: none;
  z-index: 1;
}

/**** Isotope CSS3 transitions ****/

.isotope,
.isotope .isotope-item {
  -webkit-transition-duration: 0.8s;
     -moz-transition-duration: 0.8s;
      -ms-transition-duration: 0.8s;
       -o-transition-duration: 0.8s;
          transition-duration: 0.8s;
}

.isotope {
  -webkit-transition-property: height, width;
     -moz-transition-property: height, width;
      -ms-transition-property: height, width;
       -o-transition-property: height, width;
          transition-property: height, width;
}

.isotope .isotope-item {
  -webkit-transition-property: -webkit-transform, opacity;
     -moz-transition-property:    -moz-transform, opacity;
      -ms-transition-property:     -ms-transform, opacity;
       -o-transition-property:      -o-transform, opacity;
          transition-property:         transform, opacity;
}

/**** disabling Isotope CSS3 transitions ****/

.isotope.no-transition,
.isotope.no-transition .isotope-item,
.isotope .isotope-item.no-transition {
  -webkit-transition-duration: 0s;
     -moz-transition-duration: 0s;
      -ms-transition-duration: 0s;
       -o-transition-duration: 0s;
          transition-duration: 0s;
}

.selected {
  border-bottom: 2px solid $primary-color;

}

And of course do not forget to add isotope.js file to your html

Vinay Raghu over 5 years ago

Hi, I have tried using foundation columns with isotope and realized that isotope works best with fixed column widths and not responsive columns(that ship with foundation). So the best way to go about this is to define set widths for your columns.

If you look at masonry examples, there are different sizes but they all have set widths.
If you look at pinterest, only the heights are variable and the widths are set

When we tried this at http://www.runway2street.com, I realized that freewall is a better option for us as it has a default pinterest layout that expands your columns to take up the available screen space.

http://vnjs.net/www/project/freewall/
http://vnjs.net/www/project/freewall/example/pinterest-layout.html

TL;DR don't mix your foundation grid with isotope. They work differently. You can still achieve it but fixed width columns work better for isotope. Check out Freewall project

Goodluck!

Malou Geurts over 5 years ago

So, today I finally started to work on it. I integrated the imagesLoaded script and used the code Loc supplies and after figuring out the hierarchy of the rows and columns it's now working like a dream!

This means I can use this solution in all upcoming client work (once I get my business off the ground).

I wanted to thank you all for the input, and especially Loc with the simple example! :D

andrea tagliazucchi over 5 years ago

Hi Malou,
i did follow Loc answer as well. Works great but since i have image + text (wrapped in a .panel) i have a problem when i do resize viewport: the image width does not match the panel width so i got a very ugly effect. Any hint?

Malou Geurts over 5 years ago

Do you use the imagesLoaded script? (You can find it on Desandro's website.) I included the imagesLoaded first (masonry uses it as a dependency), so Masonry won't take effect until the images have taken up full space and influenced the size of the elements. (My images take up 100% width in the columns).

Do you have an example of your problem?

andrea tagliazucchi over 5 years ago

yes i did. my problem is the panel element below images

<!doctype html>







Wanda | Popular


<!-- Navigation -->

<div class="fixed">
    <nav class="top-bar" data-topbar>
        <ul class="title-area">
            <li class="name">
                <h1><a href="#">Wanda</a>
                </h1>
            </li>
            <li class="toggle-topbar menu-icon"><a href="#">Menu</a>
            </li>
        </ul>

        <section class="top-bar-section">
            <!-- Left Nav Section -->
            <ul class="left">
                <li><a href="#">Blog</a>
                </li>
            </ul>

            <!-- Right Nav Section -->
            <ul class="right">
                <li class="active"><a href="#">Popular</a>
                </li>
                <li class=""><a href="#">Friends Event</a>
                </li>
                <li class=""><a href="#">Add Item</a>
                </li>
                <li class=""><a href="#">Me</a>
                </li>
                <li class="has-dropdown">
                    <a href="#">Settings</a>
                    <ul class="dropdown">
                        <li><a href="#">Profile</a>
                        </li>
                        <li><a href="#">Find &amp; Invite Friends</a>
                        </li>
                        <li><a href="#">Share Settings</a>
                        </li>
                        <li><a href="#">Terms and Privacy</a>
                        </li>
                        <li><a href="#">Reset Password</a>
                        </li>
                        <li><a href="#">Logout</a>
                        </li>
                        <li><a href="#">Delete My Account</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </section>
    </nav>
</div>
<br>

<!-- End Navigation -->


<div class="row">

    <!-- Side Bar -->
    <div class="large-4 medium-4 small-12 columns" itemscope itemtype="http://schema.org/Product">
        <a href="#">
            <img itemprop="image" src="img/pin3.jpg" alt="desc">
        </a>
        <div class="panel panel-masonry">
            <h5 itemprop="name">Item Name</h5>
            <div class="row">
                <div class="large-8 medium-8 small-8 columns">
                    <h6 class="subheader" itemprop="brand">Brand name</h6>
                </div>
                <div class="large-4 medium-4 small-4 columns" itemscope itemtype="http://schema.org/AggregateRating">
                    <h6 class="subheader" itemprop="ratingValue">wants</h6>
                </div>
            </div>
            <h6 class="subheader" itemscope itemtype="http://schema.org/Offer">
                <span itemprop="price">$1,000.00</span>
            </h6>
            <hr>
            <!-- row for image and user name lastname-->
            <div class="row">
                <a href="#">
                    <div class="small-4 medium-4 large-4 columns">
                        <img class="user-image" src="img/pin1.jpg" alt="name lastname" />
                    </div>
                    <div class="small-8 medium-8 large-8 columns">
                        <p>Name Last_name</p>
                    </div>
                </a>
            </div>
        </div>
    </div>
    <!-- End Side Bar -->

    <!-- Masonry container -->
    <div class="large-8 medium-8 small-12 columns">
        <div id="container" class="js-masonry" data-masonry-options='{ "itemSelector": ".item" }'>


            <!-- items -->
            <div class="small-6 medium-6 large-4 columns item" itemscope itemtype="http://schema.org/Product">
                <a href="#">
                    <img itemprop="image" src="img/pin3.jpg" alt="desc">
                </a>
                <div class="panel panel-masonry">
                    <h5 itemprop="name">Item Name</h5>
                    <div class="row">
                        <div class="large-8 medium-8 small-8 columns">
                            <h6 class="subheader" itemprop="brand">Brand name</h6>
                        </div>
                        <div class="large-4 medium-4 small-4 columns" itemscope itemtype="http://schema.org/AggregateRating">
                            <h6 class="subheader" itemprop="ratingValue">wants</h6>
                        </div>
                    </div>
                    <h6 class="subheader" itemscope itemtype="http://schema.org/Offer">
                        <span itemprop="price">$1,000.00</span>
                    </h6>
                    <hr>
                    <!-- row for image and user name lastname-->
                    <div class="row">
                        <a href="#">
                            <div class="small-4 medium-4 large-4 columns">
                                <img class="user-image" src="img/pin1.jpg" alt="name lastname" />
                            </div>
                            <div class="small-8 medium-8 large-8 columns">
                                <p>Name Last_name</p>
                            </div>
                        </a>
                    </div>
                </div>
            </div>


            <!-- items -->
            <div class="small-6 medium-6 large-4 columns item">
                <a href="#">
                    <img src="img/pin5.jpg" alt="desc">
                </a>
                <div class="panel panel-masonry">
                    <h5>Item Name</h5>
                    <div class="row">
                        <div class="large-8 medium-8 small-8 columns">
                            <h6 class="subheader">Brand name</h6>
                        </div>
                        <div class="large-4 medium-4 small-4 columns">
                            <h6 class="subheader">NR. wants</h6>
                        </div>
                    </div>
                    <h6 class="subheader">$000.00</h6>
                </div>
            </div>

            <!-- items -->
            <div class="small-6 medium-6 large-4 columns item">
                <a href="#">
                    <img src="img/pin6.jpg" alt="desc">
                </a>
                <div class="panel panel-masonry">
                    <h5>Item Name</h5>
                    <div class="row">
                        <div class="large-8 medium-8 small-8 columns">
                            <h6 class="subheader">Brand name</h6>
                        </div>
                        <div class="large-4 medium-4 small-4 columns">
                            <h6 class="subheader">NR. wants</h6>
                        </div>
                    </div>
                    <h6 class="subheader">$000.00</h6>
                </div>
            </div>

            <!-- items -->
            <div class="small-6 medium-6 large-4 columns item">
                <a href="#">
                    <img src="img/pin7.jpg" alt="desc">
                </a>
                <div class="panel panel-masonry">
                    <h5>Item Name</h5>
                    <div class="row">
                        <div class="large-8 medium-8 small-8 columns">
                            <h6 class="subheader">Brand name</h6>
                        </div>
                        <div class="large-4 medium-4 small-4 columns">
                            <h6 class="subheader">NR. wants</h6>
                        </div>
                    </div>
                    <h6 class="subheader">$000.00</h6>
                </div>
            </div>

            <!-- items -->
            <div class="small-6 medium-6 large-4 columns item">
                <a href="#">
                    <img src="img/pin8.jpg" alt="desc">
                </a>
                <div class="panel panel-masonry">
                    <h5>Item Name</h5>
                    <div class="row">
                        <div class="large-8 medium-8 small-8 columns">
                            <h6 class="subheader">Brand name</h6>
                        </div>
                        <div class="large-4 medium-4 small-4 columns">
                            <h6 class="subheader">NR. wants</h6>
                        </div>
                    </div>
                    <h6 class="subheader">$000.00</h6>
                </div>
            </div>
        </div>
        <!-- end Masonry container -->
    </div>
</div>


<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/foundation/js/foundation.min.js"></script>
<script src="js/app.js"></script>
<script>$(document).foundation();</script>
<script src="js/masonry.pkgd.min.js"></script>
<script>
    var $containter = $('#container');
    $containter.imagesLoaded( function(){
        $containter.masonry({
            itemSelector: '.item',
        }); 
    });
</script>

this is my custom CSS

.item {
padding: 0.2em;
}

.panel-masonry {
padding: 0.2em;
margin:0;
overflow: hidden;
}

.user-image {
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
}

Malou Geurts over 5 years ago

Wow that is a lot of code (if you don't mind cutting it down to the parts that actually use masonry), lemme take a look at it. But before I do that:

<script>
    var $containter = $('#container');
    $containter.imagesLoaded( function(){
        $containter.masonry({
            itemSelector: '.item',
        }); 
    });
</script>

You misspelled container, so maybe that is why the script isn't initializing?

andrea tagliazucchi over 5 years ago

Saw it.
i figured out that masonry does not include images loaded library so i add
Javascript
<script src="js/imagesloaded.pkgd.min.js"></script>

and now the reload is perfect.

Panel: i figured out that in order to have the image resizing with the panel i just needed to add

.item img {
  width: 100%;
}

That was trivial!

thanks for your help

Malou Geurts over 5 years ago

Good to hear it's solved!

I had to download the imagesLoaded script separately as well and all my images are set to max-width: 100% by default, so we have basically the same settings.

The script uses the first image to determine the width of the elements (which is why imagesLoaded is so important), so I suggest you also set it to max-width to prevent upscaling of smaller images, but that is a personal preference.

I also recommend adding height: auto; to the images while you're at it just to make sure they don't transform into weird shapes. :)