Reorder and filter items with a nice shuffling animation.



I love Mac apps, especially for their attention to detail. CoreAnimation makes it so easy to create useful and eye-pleasing effects, like the one in this video. Quicksand aims at providing a similar experience for users on the web.


How it works

At the very basic level, Quicksand replaces one collection of items with another. All you need to do is provide those two sets of items. You can do it in a couple of ways:

  1. Use plain HTML, like an unordered list.
  2. Download data by an Ajax call
  3. Transform HTML items by JavaScript (for example, sort them differently)


$('#source').quicksand( $('#destination li') );

This will work for the following HTML:

<ul id="source">
  <li data-id="iphone">iOS</li>
  <li data-id="android">Android</li>
  <li data-id="winmo">Windows Phone 7</li>

<ul id="destination" class="hidden">
  <li data-id="macosx">Mac OS X</li>
  <li data-id="macos9">Mac OS 9</li>
  <li data-id="iphone">iOS</li>

Please note that data-* is a perfectly valid HTML5 attribute. If you’re using older doctype, you can use a different attribute or even a custom function to identify unique elements. See the examples for more.

First container (source) is visible to the user. Second container (destination) is provided as the first argument of Quicksand.

You need data-id attributes so that the plugin can identify the same elements within source and destination collections. If elements exists in both collections (the same data-id), it’s the same to Quicksand.

If you want to include a callback function, add it as a last argument:

$('#source').quicksand( $('#destination li'), function() {
  // callback code

CSS recommendations

  1. When styling your items and their container, please use CSS class. Using ID may lead to strange results. Quicksand clones the container to simulate destination frame of the animation. Since it's impossible for two elements of the same ID to exist, styling your items/container via container ID should be avoided.
  2. Quicksand needs to know the margin of body, container and collection items. If these elements have their margins, please use px (pixels), not ems. The plugin doesn't understand ems for now.


You can modify Quicksand by using optional parameters argument.

$('#source').quicksand( $('#destination li'), {
  name: value


$('#source').quicksand( $('#destination li'), {
  name: value
}, function() {
  // callback code

List of available params:

Name Default Description
adjustHeight 'call' Adjusts the height of container to fit all the items, 'call' for automatically adjusting before or after the animation (determined automatically), 'dynamic' for height adjustment animation, 'auto' to set the value to 'auto', false for not doing absolutely anything about it (useful on responsive pages).
adjustWidth false Adjusts the width of container to fit all the items, 'call' for automatically adjusting before or after the animation (determined automatically), 'dynamic' for width adjustment animation, 'auto' to set the value to 'auto', false for not doing absolutely anything about it (useful on responsive pages).
attribute 'data-id' Attribute used to match items in collections. You can provide custom function to extract unique values (see the demos)
duration 750 How long the animation will take. In milliseconds.
easing 'swing' Easing for the animation. Use jQuery easing plugin for more easing options.
enhancement function() {} Since v1.5, this shouldn't be needed in most cases. If you wish to integrate their visual enhancements (eg. font replacement) or attach click/hover events on new sorted elements, specify a function that refreshes or re-applies enhancement to an item during the animation.
useScaling false Use scaling (CSS3 transform) animation. Requires to include this plugin to your project.
retainExisting true By default, Quicksand reuses existing DOM elements instead of replacing them (new in v1.3). Set this option to false to brutally replace the collection with a fresh one when the animation ends. This in most cases shouldn't be required, but might be useful in some circumstances.
maxWidth 0 Hide all elements whose left CSS property is greater than this value. Setting this option to 0 turns this behavior off.
atomic false Set to true to swap the DOM elements immediately. Turning this option on will make the animation look less effective but will make your life easier if you intend to modify the DOM during the animation.


Version 1.2 brought major performance tweaks out of the box. To improve performance, you can:

  1. turn off useScaling option to stop using CSS3 transforms in the animation
  2. stop using adjustHeight: 'dynamic' in favor of false or 'auto'.

Integration with other plugins

When your items have functional enhancements (eg. tooltips), remember to use callback to apply them on newly cloned objects:

$("#content").quicksand($("#data > li"), 
    duration: 1000,
  }, function() { // callback function
    $('#content a').tooltip();

When your items are visually enhanced (eg. font replacement), use enhancement function to refresh/apply the effect during the animation:

$("#content").quicksand($("#data > li"), 
    duration: 1000,
    enhancement: function() {
      Cufon.refresh('#content span');


As it was stated earlier, Quicksand works by comparing two collections of items and replacing them. It’s that simple.

Advanced demonstrations include custom jQuery code to achieve some of the goals, like sorting or making Ajax calls. This code can be copied & used freely, but it’s not part of the plugin.

  1. Two different sets of HTML
  2. Two sets of HTML with overlapping elements
  3. Advanced: Sorting one set of HTML (cloning)
  4. Advanced: Custom attribute function (getting rid of data-* attributes)
  5. Advanced: Ajax call

So, go ahead and…


  1. Can I use use Quicksand in commercial projects?

    Yes! You can use it commercially without limitation, you can even use it in website templates you sell on ThemeForest.

  2. I get an error TypeError: Result of expression ... easing ... [undefined] is not a function. What happened?

    You are using easing effect that's not built-in and forgot to include jQuery.easing plugin. You can download it from its home page. Alternatively, remove easing from your Quicksand options to stick with the default swing effect. It's not that bad!

  3. I would like to filter my items in a different way. How can I do it?

    There's only one thing that Quicksand can do and it's performing the animation. Quicksand does not filter and does not do any sorting. It's up to you to provide initial collection and destination collection. A little bit of custom programming is required.

  4. How can I use Quicksand with radio buttons instead of links? I want to combine criteria when filtering my collection.

    You need to learn how to use callbacks in jQuery to handle changes in forms. Next, you have to study jQuery selectors to filter items the way you like. Quicksand generates the animated transition between elements. It's up to you to filter and sort.

  5. I'm a designer and I don't know how to start...

    This plugin requires basic programming skills: using jQuery selectors and callbacks is a minimum knowledge required to implement it on your website. Copy-paste is cool but sorry, not this time. Good luck studying jQuery, it's not that hard!

Other crap

Requirements and dependencies

Browser compatibility

The plugin should work in all browsers, including versions a few years behind. Internet Explorer 7 is the lowest supported version of IE.

Extra credits

Huge thanks go to Piotr Petrus for organizing the documentation, making demos and creating this stunning design.


Copyright © 2010 Jacek Galanciak, released under both MIT and GPL version 2 license.