Install

bower install shufflejs

Shuffle is also available on NPM as shufflejs.

Example

Filter:

Sort:

Baseball

photography

Tennis

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!

iMac

wallpaper, 3d

Master Chief

graphics

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!

Eightfold

wallpaper, 3d

Pumpkin

photography

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!

Vestride

wallpaper, 3d

Newegg

graphics

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!

Arc

wallpaper

Ground

photography

Grass

wallpaper

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!

Vestride

wallpaper, 3d

Features

  • 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)

Options

Settings you can change (these are the defaults).

// Overrideable options
Shuffle.options = {
  group: ALL_ITEMS, // Initial 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. Use an element to determine the size of columns and gutters.
  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).
  columnThreshold: HAS_COMPUTED_STYLE ? 0.01 : 0.1, // Reading the width of elements isn't precise enough and can cause columns to jump between values.
  initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method.
  throttle: throttle, // By default, shuffle will throttle resize events. This can be changed or removed.
  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: CAN_TRANSITION_TRANSFORMS // Whether to use transforms or absolute positioning.
};

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

Usage

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>
    </div>
  </figure>
  <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>
    </div>
    <p class="picture-item__description">Some description here.</p>
  </figure>
  <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>
    </div>
  </figure>
  <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>
    </div>
    <p class="picture-item__description">Some description here.</p>
  </figure>
</div>

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');

  $grid.shuffle({
    itemSelector: '.picture-item',
    sizer: $sizer
  });
});

Events

A list of events shuffle triggers:

  • 'loading.shuffle'
  • 'done.shuffle'
  • 'layout.shuffle'
  • 'removed.shuffle'

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 );
});

Sorting

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>
</select>
<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.

Example

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

Searching

// 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').append($items);
$('#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);

Public Methods

A list of the methods available to you and what they do.

  • shuffle - Filters all the shuffle items.
  • sort - Sorts the currently filtered shuffle items.
  • update - Repositions everything. Useful for when dimensions (like the window size) change.
  • layout - Use this instead of update() if you don't need the columns and gutters updated. Maybe an image loaded and now has a height.
  • appended - New items have been appended to the shuffle container.
  • disable - Disables Shuffle from updating dimensions and layout on resize.
  • enable - Enables Shuffle again.
  • remove - Remove one or more shuffle items.
  • destroy - Destroys Shuffle, removes events, styles, classes, and references.

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.

Dependencies

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

Changes

  • v3.1.0 3/23/15 - Allow zero speed option (#64) and cancel previous animations instead of ignoring new ones (#69). Handle non-integer columns better (#46)
  • v3.0.4 2/16/15 - Publish to NPM.
  • v3.0.2 1/21/15 - Remove from jQuery plugins directory.
  • v3.0.1 12/29/14 - Add CommonJS support.
  • v3.0.0 10/06/14 - Refactored with improvements, added unit tests, more documentation. Removed some triggered events.
  • v2.1.2 6/01/14 - Use window.jQuery instead of window.$ to work better with noConflict. Fixed #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