Q&A: The Pinterest-Style Grid a.k.a Masonry

I’ve had a lot of clients and designers ask me about creating a “Pinterest-style” grid for their website, and when someone asked on Twitter earlier this week for a recommendation of a jQuery plugin to handle the effect, I thought it was probably time for a tutorial.

About the Technique

If you’re just kind of curious about this technique, this first section is probably all you’ll really want to read. The later portion of the post gets into a more in-depth tutorial with code, but let’s start by talking terminology and reasons you’d actually want to use this layout model.

Technical Terminology

The actual name for this style of cascading “grid” where images or boxes of varying heights and widths flow neatly together with even spacing is masonry layout or masonry grid. Underneath the name is the idea that the “bricks” of the layout can vary but the spacing between (where the mortar would be, or in layout terms, the margins) is always consistent.

Pinterest is definitely the best-known example but if you’re looking for wider information or examples of the technique, masonry is the broader term to use.

From a Strategy Perspective

When compared to more traditional grids with a fixed height and width for every item in the grid, masonry grids have the advantage of NOT limiting the images that can be displayed. Whereas traditional grids require images to be cropped to fit, with a masonry layout the person maintaining the content will never have to think about aspect ratio when uploading their grid images.

This is especially nice for photographers, who usually want to highlight their composition by displaying the complete image for each photo:

Sabra Lattos masonry grid

Sabra Lattos Photography, designed by small shop

It’s also a great technique for situations where you’ve got to use third-party graphics that may not be uniform, as in this example that showcases event posters:

Rare Device shows grid

Rare Device, designed by Meg Lewis of Ghostly Ferns for Aeolidia

And in this example showing products from a variety of websites:

The American Edit Must-Haves grid

The American Edit, designed by MAEMAE Paperie

Masonry grids are a nice way to break up a page layout and keep things feeling consistent while allowing for variety, as in this example, where longer quotes are accommodated without making the page feel unduly messy (also, note that the layout model works for both text and images):

GREER Chicago Press & Praise grid

GREER Chicago, designed by Meg Lewis of Ghostly Ferns for Aeolidia

Create Your Own Masonry Layout

Now for the technical part of the post, let’s look at how to actually make this kind of layout happen. There are a couple of different jQuery plugins out there for this, but my favorite is David DeSandro’s Masonry.

History Note

For those of you who are into this sort of thing, I am fairly certain that this Masonry plugin was the original inspiration/ tool behind Pinterest’s version. I’ve had that in my head for awhile now, but when I went to check Google to see if I could verify it as fact, the closest I could get was this old post where the author hints that Pinterest based theirs on his but specifies that they use their own version. So not totally conclusive, but pretty close.

Anyway, Step 1: Include the Scripts

As with any jQuery integration, one of the first steps is to actually include the scripts in your site.

Expand for WordPress Directions

In WordPress, it turns out Masonry is already bundled with WordPress core (as are a number of common scripts), so you don’t even have to upload the file yourself. However, the version bundled is currently a bit behind so you may want to handle it manually until that gets updated.

If you’re using the bundled version, all you’ll do is enqueue it using the name WordPress has given it:

/**
 * ENQUEUE SCRIPTS
 */
function emitheme_scripts_method() {
  wp_enqueue_script(
    "jquery-masonry",
    array("jquery")
  );
}
add_action("wp_enqueue_scripts", "emitheme_scripts_method");

The second parameter makes sure jQuery is loaded before Masonry, and while the current version of Masonry doesn’t actually require jQuery I believe the WordPress-bundled version does.

If you were only using Masonry on a particular page template, you could use a conditional to only enqueue the script on that page, e.g.:

/**
 * ENQUEUE SCRIPTS
 */
function emitheme_scripts_method() {
  if ( is_page_template( "page-masonry.php" ) ) :   
    wp_enqueue_script(
      "masonry",
      array("jquery")
    );
  endif;
}
add_action("wp_enqueue_scripts", "emitheme_scripts_method");

In case you’re wondering, Emi is the name of my starter theme, which will be released in the next week or so.

If you want to use the most recent version of Masonry, you’d download the file from the masonry site and then upload it to your theme and your enqueue snippet would look like this:

/**
 * ENQUEUE SCRIPTS
 */
function emitheme_scripts_method() {
  if ( is_page_template( "page-masonry.php" ) ) :   
    wp_enqueue_script(
      "masonry",
      get_template_directory_uri() . "/assets/vendor/masonry.pkgd.min.js",
      array("jquery")
    );
  endif;
}
add_action("wp_enqueue_scripts", "emitheme_scripts_method");

Note the added file path parameter.

Evidently, this version issue is on the radar to be fixed but that fix introduces some other interesting potential issues/ differences, which you can read about in the Trac ticket notes if you’re so inclined.

Expand to view Shopify directions

For Shopify, the snippet to include is:

{{ "masonry.pkgd.min.js" | asset_url  | script_tag }}

That goes in the theme.liquid file in the <head></head> section.

Make sure to actually upload the file itself as well – it’ll go into your theme’s assets directory.

If you’re using images in your layout, you will likely also want to include imagesLoaded in order to have the layout adjust to the images after they’re loaded.

WordPress Example

To do this, just upload that file to your theme (I put mine inside a /assets/vendor/ directory structure), and then add it to your enqueue function:

/**
 * ENQUEUE SCRIPTS
 */
function emitheme_scripts_method() {
  if ( is_page_template( "page-masonry.php" ) ) :   
    wp_enqueue_script(
      "masonry",
      get_template_directory_uri() . "/assets/vendor/masonry.pkgd.min.js",
      array("jquery")
    );
    wp_enqueue_script(
      "imagesLoaded",
      get_template_directory_uri() . "/assets/vendor/imagesloaded.pkgd.min.js",
      array("jquery")
    );
  endif;
}
add_action("wp_enqueue_scripts", "emitheme_scripts_method");

Shopify Example

Or add another line for it in Shopify:

{{ "masonry.pkgd.min.js" | asset_url  | script_tag }}
{{ "imagesloaded.pkgd.min.js" | asset_url  | script_tag }}

Step 2: Create the markup

The markup structure is pretty simple, just a container with a bunch of items in it. For example:

<div id="grid">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

If this were a grid of posts in WordPress, the loop might look something like:

<?php if ( have_posts() ) : ?>
  <div id="grid">
    <?php while ( have_posts() ) : the_post(); ?>
      <div class="item">
        <?php the_post_thumbnail(); ?>
        <h2><?php the_title(); ?></h2>
      </div>
    <?php endwhile; ?>
  </div>
<?php endif; ?>

It doesn’t have to be <div> elements in the group – it could be list items or just images.

As a note about images – I find it helpful to include the width and height in the image markup. In WordPress, this isn’t automatically there depending on which image template tag you use, so just something to keep in mind.

Step 3: Initialize Everything

Here is the snippet to initialize Masonry on your grid:

<script>
jQuery(document).ready(function($){
  var $container = $("#grid");
  // initialize Masonry after all images have loaded  
  $container.imagesLoaded( function() {
    $container.masonry({
      columnWidth: 150,
      itemSelector: ".item",
      gutter: 15
    });
  });
});
</script>

You can put that in a number of places depending on how you’re setting up your theme but a good place to start if you’re not sure would be in the footer, before the closing </body> tag.

If you are NOT using imagesLoaded then your snippet would be more like:

<script>
jQuery(document).ready(function($){
  $("#grid").masonry({
    columnWidth: 150,
    itemSelector: ".item",
    gutter: 15
  });
});
</script>

We’ve set three options in those snippets:

  • Column Width (adjust that to match your items/ layout)
  • Item Selector (the class on your grid items, or you could do something like #grid li if you were using a list)
  • Gutter, which is the horizontal spacing

All the various options are listed on the Masonry site.

Step 4: Style It

I typically give my items some basic CSS styling to get started:

.item {
  float: left;
  margin-bottom: 15px;
  text-align: center;
}

The bottom margin handles the vertical spacing, where the gutter option handed the horizontal spacing. Usually I want to center all the content in each grid item, so the text-align handles that as well.


There you have it, Masonry grids!

Q&A: Four Methods for Client Education & Training

Q&A: Client Education & Training

I’ve been asked a few different times how I handle teaching clients to manage and update their content once their site is finished. While I enjoy hearing from my clients after we’ve wrapped a project and often work with people ongoing to add templates or on new projects, it’s important to me that clients are able to manage all of their content without relying on me and my team.

In order to make that happen, I use four different methods for sharing information with clients and training them to use the content management system to manage their content and their site as a whole.

1. Documentation

For early decision points and also for general information on website concepts, I provide a lot of documentation in written format in one of two places.

Blog Posts on Common Topics

A lot of my documentation for clients is right here on my blog. Many of my posts are just elaborations on answers I’ve first sent to clients via email, which is great because once they’re published I can just send the link instead of re-answering the question.

My posts on backing up & updating WordPress, prepping images for the web and aspect ratios are all examples of blog posts that started out as client education emails.

Non-Post Documentation

This is for things that come up again and again in email conversation with clients but aren’t necessarily right for blog posts, I’ve started compiling additional documentation via HelpScout using their Docs feature.

Documentation via HelpScout

There is some overlap between this content and my FAQ page. The difference is that the HelpScout documentation, while not protected or completely hidden, is intended for clients, whereas the FAQ is more public-facing. The integration with HelpScout email (which I use for my general email inbox, shared with my business assistant) is partly what makes this a great system for us, as we can really easily insert links to the articles into emails.

2. Admin Structures

When we’re actually building a site, my team and I make sure to prioritize the content management experience of the end user, making it easy for the client to update their content even when it means a little more work for us.

While this is not explicitly part of client education, it is an approach that makes our client education needs down the line more manageable.

Example Admin Structures

In practice, this means we use tools like Advanced Custom Fields to create really clean, nice-looking, intuitive admin screens specific to each page template.

Scouted Recommendations Model

Click to zoom, from the Scouted NYC case study

You can see more examples of how we’ve done this for various sites by looking through my case studies.

3. General Tutorials

Since I use existing content management systems that already have great structures for many things a client will need to do, I also make make use of existing documentation where possible. This saves time but also ensures that clients get really really great information – better than I’d be able to provide.

WordPress Video Tutorials

For WordPress, I provide clients with access to WP101′s premium video tutorials, which I’ve licensed and share via a private area on my site:

WP101 page on ZoeRooney.com

These videos cover all the WordPress “basics” including working with blog posts, categories, comments, menus, widgets, and plugins. The videos are a higher quality than I’d be able to provide and are updated with changes to WordPress core.

Shopify Written Documentation

For Shopify, I link out to specific pieces of documentation in the Shopify manual and I’ve also been impressed with the third-party Shopify & You e-book (affiliate link), which is $39 and very very thorough.

4. Custom Tutorials

While those general resources have proven to be quite helpful, since we customize the admin to handle the various page templates we’re creating for clients I typically also create a informal video tutorial covering our customizations. I’ve found that video is great because the client can watch and re-watch it at their convenience, rather than feeling like they have to absorb all the information in real-time via a screen share or real-time training session.

Example Site-Specific Video Tutorial

Here’s an excerpt from a recent tutorial I created for Clara Persis:

That’s about half the video, and the rest of it walks through the remainder of the pages.

Underneath the Videos

You can see from watching that example that these videos are not rehearsed – it is just me talking through the pages and features one by one the same way I’d do it if I were sitting at the computer next to Clara. The informal, unscripted nature ensures that I can record these videos quickly, which keeps it feasible.

Technology-wise, I use Quicktime (the regular version that comes with Macs) to record along with the microphone built into my UrbanEars headphones. I then upload the video my Vimeo Pro account via the built-in Quicktime “Share” feature and email the review page link to the client, with permission set such that only people with the link can access the video, no sharing is allowed, and the client can download the file to their computer if they so choose.


So that’s it – the four methods I use to education clients and help them learn to use their site! Of course, I also try to be flexible to meet clients’ individual needs, so there have been times when I’ve supplemented these methods with phone and/or screen-share training, or even with in-person training for an entire team. Usually, though, the videos and written documentation are a great, lasting solution for both me and my clients.

Show Forum Description at Top of Single Forum Page in bbPress

I’ve been playing around with bbPress for Neatly Polished – it’s only the second time I’ve used it and the first time in a context where I’ve been able to do whatever I want with it. You can set a description for each forum, which shows by default on the parent forum’s page in the area boxed in purple-ish (the second box):

bbPress forum description

In the screenshot, we’re looking at a parent forum with a couple of subforums. You can see in the screenshot that I also added the current parent forum (the one that we’re on right now) description right under the title, boxed in the brighter more orange color. (Note to Self: Next time use more disparate box colors.)

I was surprised the top description isn’t shown by default, because it makes sense to have a reminder of the forum’s purpose right on the forum page itself. Once I got into the template files and system, however, it started to make more sense.

bbPress works by putting the forum content inside the page template in the area where you’d usually have the_content(), so it turns out that the area right under the title is actually outside the bbPress-specific template.

In order to put the description there, I edited my content-page.php file (or it could be in the page.php file, depending on how your theme is structured) and added the following right below the title (lines 3-5, which are highlighted):

And now the forum description is shown if we’re on a sub-forum page, just like you see up top in the screenshot! (Better bbPress conditional via Isabel Castillo.)

Workflow for Setting Up a Custom WordPress Theme Project

I’ve been doing some work on the starter theme we use for all client projects (more on starter themes & custom work here) and thought it’d be interesting to share the current set of steps necessary to get it set up for a new project.

NOTE: I am just running through the steps in this post, not so much going into what each component or tool is or does. I would love to know which pieces don’t make sense or aren’t familiar to you so I can elaborate on them in the future.

Also, next week I’ll be launching a limited enrollment beta version of my new online course that teaches whole process in excruciating detail (along with how to actually work and customize with all of the files in the theme itself). Sign up for the WP and/or workshops lists here for first dibs.

Here’s what it currently takes to get the starter theme ready for development:

1

The theme is hosted as a private Github repository, for easy access across our team. So the first step, then, is to download the theme from Github. I could copy the local directory, but sometimes I mess that up so I just download the zip each time for now.

2

Next, I do a bunch of renaming, replacing the starter theme name with the project name. The folder itself gets a new name, and I use String Replacer to do a bulk find and replace operation to change function names and other instances throughout all the files.

3

At this point, I move the theme to the directory where it’ll live while I’m working on it (which is synced with Dropbox), and then I open it in Terminal via drag and drop. I also open the directory in Espresso, which is my text editor of choice, again by dragging the folder icon onto the application in the dock.

New theme ready for set up in Terminal and Espresso

Ready for more set up!

4

Next, I run npm install in Terminal, which installs all the Gulp dependencies (all the files needed for the tasks we run using Gulp).

5

One thing that isn’t captured by my bulk find-and-replace is the theme meta information in the stylesheet, so I update that next in Espresso by editing the /scss/style.scss file. Once that’s updated, I switch back to Terminal and run gulp to compile the CSS for the first time (getting my main directory style.css all set up with the new meta info).

6

Next, I run through a set of steps to set up version control using Git. I’ve historically used Tower, which is a Git GUI, to handle these steps because it’s been easier as I’ve gotten more comfortable with Git. Now that I feel more at ease in Terminal, I’ve done this a few times on the command line as well, just because I’ve been too lazy to open Tower. Either is fine, I try not to stress about the method too much. The general flow is: create local repository (git init), stage all the files (git add -A), run an initial commit (git commit -a -m 'initial project commit').

7

We use BitBucket for client repositories because they have unlimited free private repos (Github has a limit), so next I log into BitBucket, create a repo there for the project, and add relevant members of my team. Then, I grab the access link and jump back to Terminal to push my local repository up to the remote version (for backup and cross-team access) using git remote add and git push.

8

Next, depending on the project we often set up automatic deployment using DeployHQ so that every time we push future commits, the remote server also gets the updates. This is convenient in a development situation but I would not suggest automating it on a live site. The sub-steps for this include getting the theme directory set up on the server, connecting Bitbucket and DeployHQ (really easy – DeployHQ connects right to the Bitbucket account and lays out the steps to take on the BitBucket side), and entering server credentials in DeployHQ.

9

At this point, I’m ready to work on the theme itself, and all that setup ensures that much of my process from here out is nicely automated (Sass processing, version control, even deployment)!


Improving Efficiency

Clearly, this setup process is not the most efficient thing in the world, although it’s gotten quicker with practice. We’ve been working on automating some of these steps using Yeoman, which I’ll share more about once we get it fully up and running. I’ll also be making my starter open source in the near future, once we’ve done a bit more cleanup.

Update: About all those tools

I realized after writing this post that I name-dropped a ton of stuff without really explaining what it is (Grunt, Gulp, git, etc.) so I wrote a follow up post explaining what they are and why I use them.

Create a Blog Editing Checklist with Custom Fields

create a blog editing checklist

Last week I wrote about how I use a custom taxonomy to track status across my running blog post drafts. In addition to that system, I use internal-only custom fields to maintain an editing and proofreading checklist on each individual post.

I’ve used the Advanced Custom Fields plugin to create this functionality, a great choice because it’s free, has a nice interface, and is independent from my theme (especially since we’re only using the fields in the admin).

The setup is fairly straightforward:

1. Create a new checklist field

Checklists are a built in option with ACF, where you just list the options on their own lines in the provided box. Here’s what my field looks like on the back end:

Custom fields editing checklist setup using Advanced Custom Fields plugin

If you’re looking for ideas as far as what you might include in your own checklist, check out this fairly comprehensive editing checklist from Shareaholic.

2. Set up the field view options

I’ve set my checklist to only appear on blog post edit screens, although it could potentially be useful for pages or custom post types depending on the site. I’ve also set it to display in a standard meta box because that makes it look more consistent with the rest of the edit screen.

Field options in Advanced Custom Fields plugin

3. Check away!

With those settings in place, as soon as you save the custom field it will appear on all edit screens you’ve specified in the options. (If it is mysteriously missing, check the Screen Options tab on the top right of the edit screen to make sure it’s enabled there.)

Here’s what mine looks like:

Blog post editing checklist made with custom fields

The field values are saved whenever the post is saved (no matter the status), but since we haven’t added any template code they’re only used on the admin side. That’s the goal here, so we’re done!

This method could easily be expanded to add an empty text area for notes and reminders (especially useful if you’re managing posts as a team). Those are the main use cases that come to mind but I’m sure there are more just waiting for discovery based on your individual workflow.