Tutorial: Using jQuery Masonry with WordPress

This is a short tutorial on integrating Masonry, the jQuery layout plugin, with your WordPress site. We will try to use that jQuery plugin to show a list of posts in a neatly stacked layout, similar to the one I have down here. Here’s an explanation about Masonry, from it’s home page:

Think of it as the flip side of CSS floats. Whereas floating arranges elements horizontally then vertically, Masonry arranges elements vertically then horizontally according to a grid. The result minimizes vertical gaps between elements of varying height, just like a mason fitting stones in a wall.

Here’s a visual explanation, which I took and edited to fit my layout. Pay attention to the numbers, which shows the order of the elements in your HTML code:

Understanding Masonry’s Behaviors

Using Masonry itself is pretty simple, but if it’s the first time you’re using it there can be some surprising behaviors, especially regarding element spacing. Let’s talk about that first.

Masonry allows for two different cases. First is where all elements have the same width, and you should use this:

$('#container').masonry({ singleMode: true });

The second case is where your elements have differend widths. Use:

$('#container').masonry({ columnWidth: 200 });

Where columnWidth is the width of the grid (in pixel). Masonry will then follow these two rules:

  1. Total element width = CSS width + padding-left + padding-right + border-left-width + border-right-width + margin-left + margin-right
  2. When using columnWidth, then all elements must be placed horizontally at an increment of columnWidth (e.g. for columnWidth: 200, elements will start at 0 or 200 or 400 pixels and so on). This might not be intuitive and does not work like CSS float:

    The first element has a total width of 190px and margin-right is 0. At the same time the second element has 0 margin-left, so you will probably expect both to stick to each other. However, since the columnWidth says 200px, then the second element is pushed further and starts at 200px instead.

    That will not be the case if we only have one width, though. The next element will be placed right next to the previous one according to the margin between both.

WordPress + Masonry

Okay, coding time. We’ll try to recreate my Latest Links area where all elements have the same width. First we enqueue jQuery and call the Masonry JS script in the theme’s header.php file.

<?php wp_enqueue_script('jquery'); ?>
<?php wp_head(); ?>
<script language="javascript" type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/jquery.masonry.min.js"></script>

Make sure that wp_enqueue_script appears before wp_head, and the script call appears after it. Here’s a more detailed article on how to correctly enqueue jQuery in WordPress. My Masonry JS is located in a /js folder, yours might be different.

Next, we decide how the HTML will be structured. Mine’s like this:

<div id="linky"> 
 
  <div class="boxy"> 
    <!-- post content -->
  </div> 
 
  <div class="boxy"> 
    <!-- post content -->
  </div> 
 
  ...
 
</div> <!-- #linky -->

Pretty simple. “Linky” will be the container div that will call the Masonry function, and “boxy” will be the elements that will be stacked together. The CSS is where it’s important, you want to make sure the container width and the total element widths match. For example, if you want to have four columns of elements, each having a width + padding of 190px and a margin-right of 10px, then the container will be 200 x 4 = 800px:

1
2
3
4
5
6
7
8
9
10
#linky {
  width: 800px;
  } 
 
  #linky .boxy {
  width: 170px;
  padding: 10px;
  margin-right: 10px;
  margin-bottom: 10px;
  }

Below is my PHP to generate the HTML, I’m using WP_Query to specifically fetch the latest 15 posts from my Links category:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="linky">
 
  <?php
      $linksPosts = new WP_Query();
      $linksPosts->query('showposts=15&cat=7');
  ?>
  <?php while ($linksPosts->have_posts()) : $linksPosts->the_post(); ?>
  <div class="boxy">
    <div class="read">
    <h4><a href="<?php if(get_post_meta($post->ID, "url", true)) echo get_post_meta($post->ID, "url", true); else the_permalink(); ?>"><?php the_title(); ?></a></h4>
      <?php the_content('Read the rest of this entry &raquo;'); ?>               
    </div>
  </div>
  <?php endwhile; ?>
 
</div>

Note that since Masonry saves a lot of space compared to regular floats, you will usually need plenty of elements at once to fill your container (hence 15 in my case).

Now that everything is in place, the last thing to do is to add the Masonry function, preferably right after the script call in header.php:

1
2
3
4
5
<script language="javascript" type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/jquery.masonry.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
  $('#linky').masonry({ singleMode: true });
});

And we’re done. Scroll down a little bit (or click here) to see an example; the container and element widths are different from the example CSS above, but you get the general idea.

Resources

12 Responses to “Tutorial: Using jQuery Masonry with WordPress”

  1. Michael Fields

    Hi, Thanks for the great write up. I have never even heard of Masonry before, but it looks amazing. Bookmarking this page… awesome!

  2. philippdatz

    waiting for mootools version

  3. Sid

    Wow .. Thnks for sharing .. :)

    Sid

  4. Adam

    Bookmarked with Intent on using on the Theme I’m currently working on! – I saw something like this not long ago and lost it.

    Great Post :)

  5. Odzyskiwanie Danych

    How do you find enough time to write this blog ?!?

  6. Howto Using jQuery masonry inside your wordpress themes / JAUHARI

    [...] of using this masonry inside you wordpress themes, but if you need the tutorial you could visit wplover.com. I think he already explained a lot and it’s easy to learnt. What I’m going to say [...]

  7. Deck

    hei great tutorial you got here! thanks for sharing this precious

  8. geert baven

    Thanks for your explanation.
    Did you see the latest masonry update. How would you add filter into wordpress with either categories or pages?

  9. Kevin

    Thanks for your tutorial,but in header.php

    jQuery(document).ready(function($){
    $(‘#linky’).masonry({ singleMode: true });
    });
    maybe lack the

Leave a Reply

Latest Links More →

Custom Shortlinks for WordPress

Have your own short domain name for the purpose of shortlinking? Here’s an easy way to combine that with your WordPress install.

The Quick Start Guide to Using Google Webmaster Tools With WordPress

GWT is a great, frequently updated features like showing you search queries volume, malware and crawl error diagnostics and links to your site. If you don’t use it yet, you probably need to. This will help you get started.

WordPress & jQuery Contact Form without a Plugin

I would recommend this either if you want more flexibility or to learn how to code a contact form.

Understanding and cleaning the pharma (spam) hack on WordPress

How to fix that hack:

This attack is very interesting because it is not visible to the normal user and the spam (generally about Viagra, Nexium, Cialis, etc) only shows up if the user agent is from Google’s crawler (googlebot). Also, the infection is a bit tricky to remove and if not done properly will keep reappearing.

Web Safe Fonts Cheat Sheet

An updated (written in April 2010), well researched, CC-licensed Web safe fonts cheat sheet, available both in low-res PNG and high-rest PDF. Even the article is useful as well.

The Nicest 2010 Child Theme You’ll See Today

The Timaru Mental Health Support Trust website, made for charity by Team USA (comprised by web superstars like Jason Santa Maria, Dan Mall, Liz Danzico and Automattic’s John Ford) during the FullCodePress competition, is actually a clever child theme of 2010.

More recap by JSM, Daniel Mall, and Liz Danzico.

WordPress 3.0 Theme Tip: The Comment Form

The simpler way to code comment form (once you understand how hooks and filters work).

Showing and hiding content with pure CSS3

I like it, I think it’s short and easy to understand.