Creating an animated, filterable grid of items using Shuffle.js (a free alternative to Isotope, Masonry and Quicksand)

30 July 2013, Danny Connell

For a recent project, I had to create an animated, filterable grid of staff member's photo profiles (in the style of Isotope, Masonry and Quicksand).

I wanted a free solution. Masonry and Quicksand are free, and I spent a lot of time with these but had trouble setting them up. After some Googling and experimenting I found a very simple solution using the amazing jQuery plugin shuffle.js.

Check out the demo page below then I'll explain how I built it.

View demo page | Download demo page

HTML

The only dependencies we need to include are jQuery and shuffle.js:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="jquery.shuffle.min.js"></script>

Next we need some markup for the filters (that the user clicks to rearrange the grid) and the grid of items:

<ul id="filter">
<li><a class="active" href="#" data-group="all">All</a></li>
<li><a href="#" data-group="red">Red</a></li>
<li><a href="#" data-group="green">Green</a></li>
<li><a href="#" data-group="blue">Blue</a></li>
<li><a href="#" data-group="numbers">Numbers</a></li>
<li><a href="#" data-group="letters">Letters</a></li>
<li><a href="#" data-group="square">Squares</a></li>
<li><a href="#" data-group="circle">Circles</a></li>
</ul>

<div id="grid">
<div class="item blue"  data-groups='["all", "numbers", "blue", "square"]'>3</div>
<div class="item green" data-groups='["all", "numbers", "green", "square"]'>5</div>
<div class="item blue"  data-groups='["all", "letters", "blue", "square"]'>D</div>
<div class="item red"   data-groups='["all", "numbers", "red", "square"]'>1</div>
<div class="item red circle"   data-groups='["all", "numbers", "red", "circle"]'>4</div>
<div class="item red"   data-groups='["all", "numbers", "red", "square"]'>7</div>
<div class="item green circle" data-groups='["all", "numbers", "green", "circle"]'>8</div>
<div class="item red"   data-groups='["all", "letters", "red", "square"]'>B</div>
<div class="item green" data-groups='["all", "numbers", "green", "square"]'>2</div>
<div class="item green circle" data-groups='["all", "letters", "green", "circle"]'>C</div>
<div class="item blue"  data-groups='["all", "numbers", "blue", "square"]'>9</div>
<div class="item red"   data-groups='["all", "letters", "red", "square"]'>E</div>
<div class="item blue circle"  data-groups='["all", "letters", "blue", "circle"]'>G</div>
<div class="item blue"  data-groups='["all", "letters", "blue", "square"]'>A</div>
<div class="item blue"  data-groups='["all", "numbers", "blue", "square"]'>6</div>
<div class="item green" data-groups='["all", "letters", "green", "square"]'>F</div>
</div>

Note the data-group attribute on each filter link. This states which group of items should be shown when the user clicks that filter (e.g. red, green, square, circle).

The data-groups attribute on each grid item tells us which groups each item belongs to.

CSS

Next I add some CSS to style up the filters and grid items:

#container {width: 960px; margin: 0 auto;}

#filter {list-style-type: none; margin: 0; padding: 0}
#filter li, #filter a {display: block; float: left; margin: 0}
#filter a { background: #ddd; border: 1px solid #666; text-decoration: none; padding: 5px 10px;}
#filter a.active {background: yellow;}

#grid {clear: both; position: relative}
.item {width: 230px; height: 230px; background: grey; float: left; margin-right: 10px; margin-bottom: 10px; color: #fff; font-size: 60px; text-align: center; line-height: 230px; cursor: default;}
.red {background: red;}
.green {background: green;}
.blue {background: blue;}
.circle {border-radius: 230px;}

JavaScript

The JavaScript begins by initializing the shuffle plugin:

$(document).ready(function() {

/* initialize shuffle plugin */
var $grid = $('#grid');

$grid.shuffle({
itemSelector: '.item' // the selector for the items in the grid
});

});

The itemSelector option tells the plugin which elements are the grid items.

Now to make the grid rearrange when the user clicks on a filter item:

$('#filter a').click(function (e) {
e.preventDefault();

// set active class
$('#filter a').removeClass('active');
$(this).addClass('active');

// get group name from clicked item
var groupName = $(this).attr('data-group');

// reshuffle grid
$grid.shuffle('shuffle', groupName );
});

When the filter item is clicked, first we set the active class so the user can see which filter is currenly active (lines 5 and 6).

Next we grab the group name from the aforementioned data-group attribute.

Finally we reshuffle the grid by passing the plugin the group name (line 12).

Simples!

View demo page | Download demo page

9 Comments...

  1. Great post! I'm running into a problem. And I'm hoping you can help. Here's the page I'm working on: http://www.fairmontflex.com/flex/courses. I haven't styled anything yet. I literally just used the exact CSS in your tutorial. Here's the problem. Each of the items needs to be a link. However, if I wrap the items with tags, the sorting doesn't work any more. Does that make sense? How can I have each sortable item be a link but still work with the sorting? Thanks for your help.

  2. Hi Danny ! i've just followed your tutorial and it helped me a lot,everything works great but i'm using responsive images so i can't set a specific height to "item"s, and when the page loads images are on top of each other, how could i solve this ?

    Thanks again for this great article !

  3. tony cook 2 May 2014 at 10:03am said:

    Thanks for this, without your straight forward explanation for shuffle.js I was at a loss to get it working. The author of shuffle.js should have something this easily followable on their own site.

    Cheers.

  4. Nice Work!

    Many thanks

  5. Hi there. I'm having trouble with the page that I edited using these codes. It functions properly. It filters the items in the grid and I think it works well. Just with the height of he page, it won't change in my sample page. It uses the default height of the page when it filters "all". When I filter the items with lesser results , it still uses the default height , making empty spaces below the grid. Does anyone knows how to solve this?

    Thank You in Advance.

  6. mark henry 27 June 2014 at 5:47am said:

    Is it possible to sort the grid items?

  7. Awesome tutorial! Really beneficial. Thanks so much for the share =)

  8. What if i want to put alot of content and images in one item?

  9. vijayanand 18 July 2014 at 5:05pm said:

    great post mate ,it is possible to add images in the grid area ?

Leave a Reply

Your email address will not be published. Required fields are marked *

* Copy This Password *

* Type Or Paste Password Here *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>