wallpaper, 3d

Shuffle.js is a jQuery plugin for sorting, filtering, and laying out a group of items. It’s performant, responsive, and fast. Check out the demos!


wallpaper, 3d

Master Chief


Shuffle.js is a jQuery plugin for sorting, filtering, and laying out a group of items. It’s performant, responsive, and fast. Check out the demos!


wallpaper, 3d



Shuffle.js is a jQuery plugin for sorting, filtering, and laying out a group of items. It’s performant, responsive, and fast. Check out the demos!


wallpaper, 3d



Shuffle.js is a jQuery plugin for sorting, filtering, and laying out a group of items. It’s performant, responsive, and fast. Check out the demos!







Shuffle.js is a jQuery plugin for sorting, filtering, and laying out a group of items. It’s performant, responsive, and fast. Check out the demos!


wallpaper, 3d


  • Fast - Only one forced synchronous layout (aka reflow) on init, sort, or shuffle.
  • Uses CSS Transitions!
  • Responsive (try resizing the window!)
  • Filter items by groups
  • Items can have multiple groups and be different sizes
  • Sort items
  • Advanced filtering (like searching)


Settings you can change (these are the defaults)

// Overrideable options
Shuffle.options = {
    group: 'all', // Filter group
    speed: 250, // Transition/animation speed (milliseconds)
    easing: 'ease-out', // css easing function to use
    itemSelector: '', // e.g. '.picture-item'
    sizer: null, // sizer element. Can be anything columnWidth is
    gutterWidth: 0, // a static number or function that tells the plugin how wide the gutters between columns are (in pixels)
    columnWidth: 0, // a static number or function that returns a number which tells the plugin how wide the columns are (in pixels)
    delimeter: null, // if your group is not json, and is comma delimeted, you could set delimeter to ','
    buffer: 0, // useful for percentage based heights when they might not always be exactly the same (in pixels)
    initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method
    throttle: $.throttle || null, // By default, shuffle will try to throttle the resize event. This option will change the method it uses
    throttleTime: 300, // How often shuffle can be called on resize (in milliseconds)
    sequentialFadeDelay: 150, // Delay between each item that fades in when adding items
    supported: Modernizr.csstransforms && Modernizr.csstransitions // supports transitions and transforms

No options need to be specified, but itemSelector should be used. Other common options to change are speed, easing, gutterWidth, and columnWidth (or sizer).


The HTML Structure

The only real important thing here is the data-groups attribute. It has to be a valid JSON array of strings. Optionally, it can be a string delimeted by a value you provide. See delimeter in the options.

In this example, shuffle is using the fluid grid from the Twitter Bootstrap v2.3. It's also making use of BEM class naming.

<div id="grid" class="row-fluid">
  <figure class="span3 picture-item" data-groups='["photography"]'>
    <img src="/img/baseball.png" height="145" width="230" />
    <div class="picture-item__details">
      <figcaption class="picture-item__title">Baseball</figcaption>
      <p class="picture-item__tags">photography</p>
  <figure class="span6 picture-item" data-groups='["wallpaper","3d"]'>
    <img src="/img/tennis-ball.png" height="145" width="230" />
    <div class="picture-item__details">
      <figcaption class="picture-item__title">Tennis</figcaption>
      <p class="picture-item__tags">wallpaper, 3d</p>
    <p class="picture-item__description">Some description here.</p>
  <figure class="span3 picture-item" data-groups='["wallpaper","3d"]'>
    <img src="/img/imac.png" height="145" width="230" />
    <div class="picture-item__details">
      <figcaption class="picture-item__title">iMac</figcaption>
      <p class="picture-item__tags">wallpaper, 3d</p>
  <figure class="span3 picture-item picture-item--h2" data-groups='["graphics"]'>
    <img src="/img/master-chief.png" height="145" width="230" />
    <div class="picture-item__details">
      <figcaption class="picture-item__title">Master Chief</figcaption>
      <p class="picture-item__tags">graphics</p>
    <p class="picture-item__description">Some description here.</p>

How column widths work

The columnWidth option is used to calculate the column width. You have several options:

  1. Use a sizer element. This is the easest way to specify column and gutter widths. You can use an element or an element wrapped in jQuery to define the column width and gutter width. Shuffle will measure the width and margin-left of this sizer element each time the grid resizes. This is awesome for responsive or fluid grids where the width of a column is a percentage. The sizer option is an alias for columnWidth.See a demo using a sizer element or look at the js file for the sizer demo.
  2. Use a function. When a function is used, its first parameter will be the width of the shuffle element. You need to return the column width for shuffle to use (in pixels).
  3. A number. This will explicitly set the column width to your number (in pixels).
  4. By default, shuffle will use the width of the first item to calculate the column width.

A basic setup example

If you want functional buttons, check out the js file.

$(document).ready(function() {
  var $grid = $('#grid'),
      $sizer = $grid.find('.shuffle__sizer');

    itemSelector: '.picture-item',
    sizer: $sizer


A list of events shuffle triggers:

  • 'loading.shuffle'
  • 'done.shuffle'
  • 'shrink.shuffle'
  • 'shrunk.shuffle'
  • 'filter.shuffle'
  • 'filtered.shuffle'
  • 'layout.shuffle'
  • 'removed.shuffle'

Heads up! To receive the loading event, you must subscribe to it before initializing the plugin, otherwise it will fire before you have subscribed to it.

Get notified when shuffle is done with setup

$grid.on('done.shuffle', function() {
  console.log('Finished initializing shuffle!');

// Initialize shuffle
$grid.shuffle( options );

Do something when an item is removed

$grid.on('removed.shuffle', function( evt, $collection, shuffle ) {
  console.log( this, evt, $collection, shuffle );


You can order the elements based off a function you supply. In the demo above, each item has a data-date-created and data-title attribute. When the select option menu changes, a sort object is passed to shuffle.

<select class="sort-options">
  <option value="">Default</option>
  <option value="title">Title</option>
  <option value="date-created">Date Created</option>
<figure class="picture-item" data-groups='["photography"]' data-date-created="2010-09-14" data-title="Baseball">…</figure>
// Sorting options
$('.sort-options').on('change', function() {
  var sort = this.value,
      opts = {};

  // We're given the element wrapped in jQuery
  if ( sort === 'date-created' ) {
    opts = {
      reverse: true,
      by: function($el) {
        return $el.data('date-created');
  } else if ( sort === 'title' ) {
    opts = {
      by: function($el) {
        return $el.data('title').toLowerCase();

  // Filter elements
  $grid.shuffle('sort', opts);

The opts parameter can contain two properties. reverse, a boolean which will reverse the array. by is a function that is passed the element wrapped in jQuery. In the case above, we’re returning the value of the data-date-created or data-title attributes.

Calling sort with an empty object will reset the elements to DOM order.

Advanced Filtering

By passing a function to shuffle, you can customize the filtering to your hearts content. Shuffle will iterate over each item and give your function the element wrapped in jQuery and the shuffle instance. Return true to keep the element or false to hide it.


// Filters elements with a data-title attribute with less than 10 characters
$('#grid').shuffle('shuffle', function($el, shuffle) {
  return $el.data('title').length < 10;


// Advanced filtering
$('.js-shuffle-search').on('keyup change', function() {
  var val = this.value.toLowerCase();
  $grid.shuffle('shuffle', function($el, shuffle) {

    // Only search elements in the current group
    if (shuffle.group !== 'all' && $.inArray(shuffle.group, $el.data('groups')) === -1) {
      return false;

    var text = $.trim( $el.find('.picture-item__title').text() ).toLowerCase();
    return text.indexOf(val) !== -1;

Adding and removing items

You can add and remove elements from shuffle after it has been created. This also works for infinite scrolling.

Add a collection

// Adds 2 <div>s to an existing Shuffle instance.
var $item1 = $('<div class="gallery-item item1">')
var $item2 = $('<div class="gallery-item item2">')
var $items = $item1.add($item2);
$('#my-shuffle').shuffle('appended', $items);

Remove a collection

// Remove the 2 <div>s which were just added.
var $items = $('.gallery-item');
$('#my-shuffle').shuffle('remove', $items);

Extra Features

Shuffle likely will not grow much farther than the current feature set. If you need something with drag and drop, filling in gaps, more layout modes, etc., I suggest looking into packery or isotope.


Supported Browsers

  • Chrome
  • Firefox
  • IE 7+
  • Opera
  • Safari

Browsers that don't support CSS transitions and transforms *cough* IE <= 9 *cough* will see a less cool, javascript based version of the effect.

Be Social


  • v2.1.2 6/1/14 - Explicitly use window.jQuery instead of window.$. Fixes #25.
  • v2.1.1 4/16/14 - Fix items with zero opacity overlapping visible ones in IE<10.
  • v2.1.0 4/12/14 - Register with bower as shufflejs.
  • 4/10/14 - Add AMD support.
  • 4/8/14 - Separate Modernizr into its own file and custom Shuffle build.
  • 3/8/14 - Add Bootstrap 3 demo. Fixed issue with percentage width items.
  • 10/4/13 - Moved some Shuffle instance properties to constants. Converted from 4 to 2 space indentation. Added events enum and pulled out some strings to constants.
  • 8/30/13 - Added animate-in demo.
  • v2.0.0 7/5/13 - Shuffle 2.0 with masonry, adding and removing, and more.
  • 11/3/12 - Replaced layout system with masonry. Items can now be different sizes! Added addtional examples.
  • 10/24/12 - Better handling of grid item dimensions. Added a minimal markup page.
  • 9/20/12 - Added destroy method
  • 9/18/12 - Added sorting ability and made plugin responsive. Updated to Modernizr 2.6.2
  • 7/21/12 - Rewrote plugin in more object oriented structure. Added custom events. Updated to Modernizr 2.6.1
  • 7/3/12 - Removed dependency on the css file and now apply the css with javascript