Add masonry in WordPress

Would you like to know how to use Masonry in WordPress? This article will show you the basics of getting it set up in your development project. The best thing about using Masonry in WordPress is that it is actually built into the core of WordPress. So we don’t actually have to do very much work to get it working. Good thinking WordPress!

Let’s Add Masonry In WordPress

The first thing we should start with is telling WordPress that you want to pull Masonry out of the core install and actually use it. This is done by enqueuing it in the functions.php file of your theme. Whether you are building a theme from scratch or customizing a free/premium them, open up the functions.php file and find where the stylesheets and javascript files are being enqueued. This can be in many places so dig around and hopefully the theme author will have used good commenting practices so you can easily find it. Once you do find the area, check to see if the theme you are using is already enqueuing it. It should look something like this:

// Pull Masonry from the core of WordPress
wp_enqueue_script( 'masonry' );

//Pull Masonry from a cdn
wp_enqueue_script( 'masonry', '//cdnjs.cloudflare.com/ajax/libs/masonry/3.1.2/masonry.pkgd.js' );

If you find something like this in your theme, great! That means it is ready to be used. If not then you want to add one of the above lines of code into the area where the files are being enqueued. Copy and paste it in and then let’s move on.

Next we need to use a few lines of code to tell your theme what the name of the container that is surrounding the items that will use masonry and then what the item selector and column width will be. See the following code:

    <script type="text/javascript">
        
        jQuery(window).load(function() {
      var container = document.querySelector('#ms-container');
      var msnry = new Masonry( container, {
        itemSelector: '.ms-item',
        columnWidth: '.ms-item',                
      });  
      
        });

      
    </script>

Let’s walk through this a little. The spot that says document.querySelector and in parenthesis and single quotes reads #ms-container, you can change this to whatever id you want to use as a wrapper around your masonry content. We will do more with this later. This can be anything of your choosing, just remember what you named it so we can use it later. The next spot is where it says itemSelector and columnWidth. Here we will use the .ms-item to tell Masonry which items you want to use Masonry on and also, in the css, you will give it a width percentage so determine how many columns it will have.

Before we jump into the html and css, let’s determine where the above script needs to go. I typically like to put it in the footer.php file right before the closing body tag. This is only if the masonry is going to be used on every single page. If it will only be on the home page or the page that displays all of your blog posts then put it at the bottom of that template file instead so that it only runs if it is on a page that uses Masonry in WordPress.

Now we can jump into the html and css. This is an example of the home.php template file on a project that I worked on where I implemented Masonry in WordPress.

<?php get_header(); ?>

<div class="row" id="ms-container">
     
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
                
    <div class="ms-item col-lg-6 col-md-6 col-sm-6 col-xs-12">
        
        <?php if (has_post_thumbnail()) : ?>
        
            <figure class="article-preview-image">
                
                <?php the_post_thumbnail('large'); ?>
                
            </figure>
        
        <?php else : ?>

        <?php endif; ?>
        
            <h2 class="post-title"><a href="<?php the_permalink(); ?>" class="post-title-link"><?php the_title(); ?></a></h2>
            
        <?php the_excerpt(); ?>
            
    <div class="clearfix"></div>
    
<a href="<?php the_permalink(); ?>" class="btn btn-green btn-block">Read More</a>

    <div class="clearfix"></div>
    
    </div>
                
    <?php endwhile;
                
    else : ?>

        <article class="no-posts">

            <h1><?php _e('No posts were found.'); ?></h1>

        </article>
    <?php endif; ?>
                    
                </div>
<div class="clearfix"></div>




    <script type="text/javascript">
        
        jQuery(window).load(function() {
      var container = document.querySelector('#ms-container');
      var msnry = new Masonry( container, {
        itemSelector: '.ms-item',
        columnWidth: '.ms-item',                
      });  
      
        });

      
    </script>
<?php get_footer(); ?>

The first thing to take note of is that we have a div with an id or #ms-container surrounding the loop. Make sure that this div starts before the loop and ends after the loop. Then the next thing to note is directly inside the loop is a div with the class of ms-item. You should recognize those from the script we wrote above. This div starts just inside the loop and ends just before the endwhile statement. Now everything inside of the div with the class of ms-item will become a Masonry item.

There are a few more things we need to understand. We told Masonry in the jQuery statement that we wanted the container around the Masonry items to be any div with the id of ms-container. Check. Next we said that any div with the class of ms-item would be a Masonry item. We declared that where it says itemSelector. Check. Now in the css we need to create this class ms-item and tell it to be a percentage in order to create columns. In your style.css file add this class and follow the following examples:

/* Makes two columns */
.ms-item {
width: 50%;
}

/* Makes three columns */
.ms-item {
width: 33%;
}

You may have to play with the percentages a bit to get the columns right because you might need or already have margin or padding in there which will make it look really weird if you don’t.

Congratulations! You just added Masonry in WordPress! If you have any additional questions or you see I missed something in this quick tutorial please don’t hesitate to leave me a comment. That’s right! You can now leave comments on all of my posts! Finally, right?

  • The Perky Pixel

    This is the best explanation I have seen on the web yet! I do have a question though:

    When I search through my functions.php for the masonry, I find this instead: wp_enqueue_script( ‘jquery-masonry-3’ );

    Will this still work with your code or should I add: wp_enqueue_script( ‘masonry’ ); to the functions.php either replacing the old code or adding it underneath the old code?

    Right now my masonry page is lining all of the blog posts to the left side instead of doing the masonry grid. I think the enqueue is what is causing my issue.

    Thanks a bunch!

  • Thanks Perky Pixel! What version of WordPress are you running right now? Knowing this will help me determine how to advise you. Thanks!

  • Rick Wharton

    nice. It works and it’s more manageable than visual composer’s grid masonry.

  • Thanks! Yeah I agree. That Visual Composer is usually more trouble than it is worth.

  • Thanks! Yeah I agree. Visual Composer is usually more trouble than it is worth.

  • robinson mgeni

    Great work here very clear explanation, however am facing a small issue when i try to add a sidebar on the left, am using bootstrap and i want 8 columns for main content and 4 for the aidebar, but when i add columns the masonry stop working and the post just list on 50% width of the 8 columns but do not float in the left like without the sidebar. I dont know what am missing here. I will appreciate your assistance. Great work

  • Thanks! I am happy to help. Is there a url I can see your code or can you provide it somehow?

  • robinson mgeni

    Am working locally on my server can i send the code here ?

  • Yes if you can just copy and paste your code into the comments for just the page you are adding the sidebar to I will take a look at it.

  • robinson mgeni

    get_header(); ?>

    i used your example above for easy understanding and am kinda new to wordpress

    <a href="” class=”post-title-link”>

    <a href="” class=”btn btn-green btn-block”>Read More

    jQuery(window).load(function() {

    // MASSONRY Without jquery
    var container = document.querySelector(‘#ms-container’);
    var msnry = new Masonry( container, {
    itemSelector: ‘.ms-item’,
    columnWidth: ‘.ms-item’,
    });

    });

  • Sorry this comment system did something weird to the last code. Try this code:

    <?php get_header(); ?>
    <div class=”col-sm-8″>
    <div class=”row” id=”ms-container”>

    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>

    <div class=”ms-item col-lg-6 col-md-6 col-sm-6 col-xs-12″>

    <?php if (has_post_thumbnail()) : ?>

    <figure class=”article-preview-image”>

    <?php the_post_thumbnail(‘large’); ?>

    </figure>

    <?php else : ?>

    <?php endif; ?>

    <h2 class=”post-title”><a href=”<?php the_permalink(); ?>” class=”post-title-link”><?php the_title(); ?></a></h2>

    <?php the_excerpt(); ?>

    <div class=”clearfix”></div>

    <a href=”<?php the_permalink(); ?>” class=”btn btn-green btn-block”>Read More</a>

    <div class=”clearfix”></div>

    </div>

    <?php endwhile;

    else : ?>

    <article class=”no-posts”>

    <h1><?php _e(‘No posts were found.’, ‘webtegrity-framework’); ?></h1>

    </article>
    <?php endif; ?>

    </div>
    <div class=”clearfix”></div>
    </div><!–END COL-8 –>
    <!–START COL-4 –>
    <div class=”col-sm-4″>
    Content goes here…
    <div class=”clearfix”></div>
    </div>
    <div class=”clearfix”></div>
    <script type=”text/javascript”>

    jQuery(window).load(function() {

    // MASSONRY Without jquery
    var container = document.querySelector(‘#ms-container’);
    var msnry = new Masonry( container, {
    itemSelector: ‘.ms-item’,
    columnWidth: ‘.ms-item’,
    });

    });
    </script>
    <?php get_footer(); ?>

  • robinson mgeni

    your new code breaks my index when i add the loop, am playing with it, i will let you know,i have attached two thumbnalis

  • You may need to adjust the css. Lower the percentage used on the width of .ms-item

  • robinson mgeni

    Thanks a lot it eas just a css problem i thoutwit was the masonry, i decreased the percentage and it works fine now, thanks for the assistance

  • Anytime man! Glad you got it working.

  • Ammar Khan

    I really liked your article, it’s clear and to the point on how to do, i been looking for so many article just cutting it down to the business and you did it. One thing i didn’t understand, i can see you used Bootstrap classes along with .ms-item, than later you showed the css to give width to ms-item, but why you gave ms-item classes when bootstrap’s col-md-* already have done that you for? Also, when i use large args, the picture is too big.
    P.S – your picture displayed underneath ‘Log in with’, when i clicked the box to comment, don’t know if it is a pun intended or a error.

  • Awesome thank you! I always use some kind of fall back on my .ms-item just in case something was to go down with the Bootstrap CDN and that code stopped working I would have the width take over. Do you have an example of what the image is doing when using the large args? I am happy to help!

  • maetamorphosis

    Works great but how to change it for more columns?

  • If you change the Bootstrap columns (col-sm-6) you should get two columns. Is that not working on your site?

  • maetamorphosis

    No, but I will try again on clean installation in free time 🙂

  • Stuck in Pixels

    Thank you for this tutorial!! It saved me! 🙂

  • That’s great! I am glad you found your solution!

  • Stuck in Pixels

    I have a question. Is there any way I can exclude sticky post from being displayed within the “row” selector? I want the sticky post to display at the set width of the container.

  • Sorry for the delayed reply. Are you trying to get the ms-item to be a full 12 columns wide within the row or are you trying to have it span the full-width of the screen ( breaking out of the row) if the post is sticky?

  • My first thoughts would be to look at using an if statement using one of the built-in conditional tags “is_sticky()” to format the stick post differently. Check out the conditional tags page on the WordPress codex: https://codex.wordpress.org/Conditional_Tags#A_Sticky_Post. Let me know if I can help!

  • Thanks for this, man. I was expecting the process to be much more complicated. HOWEVER, I have an issue: Because I have my loop as list items instead of as Bootstrap columns (the framework for the site is bootstrap, but for this I didn’t want to deal with the $count issues of adding a new row every few items…just got lazy I guess…lol) I just have the li item set to 33%, everything just stacks. When I add float: left, it starts to look better, but everything’s in rows. It’s just not doing the masonry bit. I’ve tried loading masonry in the head and in the foot, but neither seems to solve the problem.

  • Urgh…I loved my own issue. My apologies. The additional script – I was putting into a custom scripts js file that loads in the footer. When I took it out of there and added it to my archive page directly – TA DA!!! That’ll teach me to try to get all fancy.

  • Hey sometimes simplicity is better! 🙂 I am happy you found a solution and that my article was able to help you build an amazing site. Keep up the good work and let me know if you need anything else!

  • Well, here’s the funny thing: On the dev site I needed to have the script on the template page itself for the masonry to work properly. I moved the site onto the live server (a GoDaddy hosting account) and all of a sudden the masonry wasn’t working. I was tearing my hair out trying to figure out why. As a last ditch effort to trouble-shoot it I put the script into the file that loads in the footer instead of in the template page. Aaaaaand now it works. SMH. So weird.

    Moral of the story: If it works on one server setup one way and not on another server setup, try calling the script differently. LOL

  • Stuck in Pixels

    the latter…sorry for the delayed reply. been very busy. i decided to scrap sticky posts altogether (for now). Thanks for taking time to address my issues. i have another issue. i’m using Equal Height Columns plugin with this masonry set up. i managed to get it worked. the only problem i’m having is for short posts i’m having blank space when it’s not needed. i was just wondering if there’s a selector for row instead of columns in your coding? I tried .row and it’s now working.

  • Gail Kearney

    Thanks for posting!! I have been trying for days to get this technique to work, and with your detailed instructions, I was finally able to do it! One question – my prevPage and nextPage links are now floating to the top of the container box, even though I have the style clear: both; applied to the CSS. Any idea why they are ignoring the clear command?

  • Reign

    Hey do you have a tutorial for creating a masonry gallery?

  • Arete0904

    This is by far the best tutorial I have seen and I have been searching for hours to find this info. Very good examples and easy explanation. I will definitely come back for more. I have one request though. I would love to see a tutorial on how to use AJAX to load post content. There are a lot of tutorials on WP and AJAX but not may on how to just load the content of a post. I tried https://stanhub.com/load-wordpress-post-content-with-ajax-and-jquery/ but this just caused the site to load veeery slow and it didn’t seem reliable. Anyway great job here, Thanks a bunch!

  • Emma Sonesson

    Hi,
    How do I get this to work with videos in posts? Thanks for good tutorial!

  • I personally don’t have one but I love WPMU and they have a pretty great one!

    https://premium.wpmudev.org/blog/add-masonry-grid-layouts-to-your-wordpress-site-with-just-css/

  • Thanks so much for the kind words! I will see what I can do for ya!

  • It should work with videos. Just make sure that you are using css to make your videos responsive so they will fit into the boxes. Let me know if you need additional help with this!

  • Stuck in Pixels

    hello again. what if i want to add the masonry to two loops on one page?

  • Stuck in Pixels

    I got it working…thanks! I just had to enclose the loops within the ms-container div and then assign ms-item class to each loop…phew!!

  • Volo Commerce

    Hi there! Where are you specifying the category the posts will come from?

  • This is just a general loop which means that all posts, no matter what category, will display here. If you would like to only display posts from a certain category you should look in the WordPress Codex https://codex.wordpress.org/Class_Reference/WP_Query

  • Adam

    Thank you, Wayne! You made this so easy to understand and follow.

  • thank you ! it works nice!

    Q: Is there a way to add a loader and show items only after the script for layout is done? or something like lazy load ?

  • Tim Kyarie

    where do you add the javascript?

  • Webdev Mcin

    Great tutorial! I added the code and it works great, however it seems to have broken pagination. Every time I click on older/newer it refreshes the page but shows the same results. Even shows page/2 in the url. Anyone else have these issues?