Let’s just take it as a given that any website nowadays has to be mobile friendly.

Fortunately this isn’t so much a hassle as an opportunity. Under that big “mobile friendly” umbrella, there are lots of design options to choose from.

For those who want to stick to a classical sidebar-content page layout, one of the questions becomes what to do with the sidebar when someone is viewing the site on small-width screens.

One common solution is to find a “break point” where at less than a pre-determined width the sidebar will be pushed down below the main page content.

There are several opinions about where that break point should happen, and that’s a topic for another post.

Wide Sidebars Are Awkward

But, say you decide on a break point that’s fairly wide. Something on the order of 750 pixels (px). At that width, if you just toss the sidebar down below the content, you end up with either a wide gutter on one or both sides of a narrow sidebar, or you end up widening the sidebar to the whole width of the screen.

Either way is a bit awkward, because the content of the sidebar is likely designed to fit into a narrower space. Most of the time that’s what it means to be a sidebar!

A 2-Column Sidebar

Taking the “move the sidebar below the content” idea one step further, you might implement a scheme that for wider small screens (many tablets) divides the sidebar into two half-width columns below the main content. It’s easy enough to do with CSS by setting the widget width to, say 48.5% with a little room for a 3%-wide margin between them. Something like:

@media screen and (max-width: 750px) {
  .sidebar {
    margin: 0 auto;
    width: 98%;
  }
  .widget {
    float: left;
    width: 48.5%
  }
  .widget:nth-child(2n) {
    margin-left: 3%;
  }
}

While it’s an improvement, when you have some widgets that are tall and others that are short, you’re likely to get unsightly gaps where the floated widgets don’t line up.

jQuery Masonry to the Rescue

Masonry is a jQuery library that lines up columns more evenly where the element heights within the columns are unequal. You’ve probably seen the idea at work on sites like Pinterest.

It’s also ideal for WordPress because it ships as part of WordPress core. All you have to do is tell WordPress to load it and then configure a short but of JavaScript to apply Masonry to your widgets. Let’s see how.

Step 0 — Tell WordPress to Load Masonry

Somewhere in your theme, you’re probably already loading styles and scripts. What you’re looking for is something in your theme’s functions.php file that calls wp_enqueue_script() or wp_enqueue_style(). If you don’t have anything that fits that description, you can add it into your own function as follows:

1. function my_theme_scripts() {
2.     wp_enqueue_script( 'masonry' );
3. }
4. add_action( 'wp_enqueue_scripts', 'my_theme_scripts' );

(If you already have a function with other wp_enqueue_script() lines going on, you can simply append line 2 above into that function.)

Pretty easy.

Step 1 — Give Your HTML Some Class

Now that Masonry is loading, you still have connect some wires for it to work with your widgets. On one end of the wire, there has to be some html to hang your Masonry on. That’s what we’ll do next.

Your widgets are in a sidebar. In most themes, the sidebar’s html will be in a file called sidebar.php. You’ll likely have a <div> or an <aside> tag that encloses the sidebar. For example, something like:

<div id="secondary" class="widget-area" role="complementary">
    <?php dynamic_sidebar( 'sidebar-1' ); ?>
</div><!-- #secondary -->

First, we need to add a class to this <div> to hang our Masonry on. Let’s add a class called grid:

<div id="secondary" class="widget-area grid" role="complementary">

Next, because we want the widths of our masonry columns to be responsive, we need to add a couple empty divs for Masonry to work with.

<div id="secondary" class="widget-area grid" role="complementary">

    <div class="grid-sizer"></div>
    <div class="gutter-sizer"></div>
</div><!-- #secondary -->

Note, you can make up your own class names for these. You’ll just need to remember what you call them later.

Step 2 — Define Your Sidebar Width Using CSS

We kinda-sorta did this before when we were just dropping the sidebar below the content without the Masonry. Only now that Masonry is going to take care of the positioning, we only need to use CSS to tell the browser about the width. We also need to add a class definition for the gutter if we want space between the columns:

@media screen and (max-width: 750px) {
  .sidebar {
    margin: 0 auto;
    width: 98%;
  }
  .widget {
    width: 48.5%
  }
  .gutter-sizer {
    width: 3%;
  }
}

Step 3 — Hook Your Classes into Masonry

Now for the other end of the wire! For this we’ll need to start a new JavaScript file in our theme. I’ll call mine masonry-init.js. In this file, we’ll start with the following code:

if (jQuery(window).width() < 750) {
    jQuery('.grid').masonry({
        itemSelector: '.widget',
        columnWidth: '.grid-sizer',
        gutter: '.gutter-sizer',
        percentPosition: true
    });

I’ve used 750 as the width of the window in pixels to make my break point. Use whatever break point you’ve decided on. Also, if you used classes other than grid and grid-sizer in step 1, above, use your own class names here, too.

Now, this is fine, as far as it goes. Masonry is going to attach itself to your sidebar widgets if the screen size is less than 750px when the page loads. But what about if the user loads at one size and then resizes the screen?

If you want to get fancy and have Masonry kick in and out when the screen resizes, we can take things one step farther:

Step 4 — Turn Masonry Off and On Again

To do this, we start by turning our little JavaScript loader into a function that we can run whenever the screen gets resized:

function do_masonry() {
    if (jQuery(window).width() < 750) {
        jQuery('.grid').masonry({
            itemSelector: '.widget',
            columnWidth: '.grid-sizer',
            gutter: '.gutter-sizer',
            percentPosition: true
        });
    }

But, now we also need to include what to do if the screen size is more than 750px. Let’s add a bit to check if Masonry is attached to our sidebar and if so, to remove it:

function do_masonry() {
    if (jQuery(window).width() < 750) {
        jQuery('.grid').masonry({
            itemSelector: '.widget',
            columnWidth: '.grid-sizer',
            gutter: '.gutter-sizer',
            percentPosition: true
        });
    } else {
        if (jQuery('.grid').masonry()) {
            jQuery('.grid').masonry( 'destroy' );
    }
}

Now we have our function to add or remove Masonry depending on screen size. We need to run this function first when the page loads, and again every time the screen gets resized. So in our masonry-init.js we add below our function:

do_masonry();

jQuery(window).resize(function() {
    do_masonry();
});

And, presto!

But what about very small screens?

Say you size all the way down to an iPhone in portrait orientation. Too skinny for a 2-column widget! With a little CSS we can add a second break point for the very small screens:

@media screen and (max-width: 400px) {
  .widget {
    width: 100%
  }
}

You don’t need to worry about adding the second breakpoint to the Masonry JavaScript because the CSS will tell Masonry about the new column width, letting Masonry re-adjust to the single column format.

Happy Coding!

Photo credit: Chilanga Clement