---
title: Isotope
layout: default
category: homepage
features:
  - name: An exquisite jQuery plugin for magical&nbsp;layouts
    symbol: Iso
    number: 1
    category: alkali
  - name: Dynamic, intelligent layouts
    symbol: Dyn
    number: 31
    category: actinoid
  - name: Re&ndash;order items with&nbsp;sorting
    symbol: Srt
    number: 27
    category: lanthanoid
  - name: Powerful methods, simple&nbsp;syntax
    symbol: Pow
    number: 61
    category: metalloid
  - name: Reveal &amp; hide items with&nbsp;filtering
    symbol: Flt
    number: 11
    category: alkaline-earth
  - name: Captivating animations
    symbol: Ani
    number: 41
    category: transition
  - name: Progressively enhanced for CSS3 transforms &amp;&nbsp;transitions
    symbol: Pro
    number: 71
    category: halogen
  - name: Sort items by just about&nbsp;anything
    symbol: Any
    number: 51
    category: post-transition
---
  
  <section id="options" class="clearfix">
    <div class="option-combo">
      <h2>Filter:</h2>
      <ul id="filter" class="option-set clearfix" data-option-key="filter">
        <li><a href="#show-all" data-option-value="*" class="selected">show all</a></li>
        <li><a href="#elements" data-option-value=".element:not(.feature)">elements</a></li>
        <li><a href="#features" data-option-value=".feature">features</a></li>
        <li><a href="#examples" data-option-value=".example">examples</a></li>
      </ul>
    </div>
    <div class="option-combo">
      <h2>Sort:</h2>
      <ul id="sort" class="option-set clearfix" data-option-key="sortBy">
        <li><a href="#mixed" data-option-value="number" class="selected">mixed</a></li>
        <li><a href="#original" data-option-value="original-order">original</a></li>
        <li><a href="#alphabetical" data-option-value="alphabetical">alphabetical</a></li>
      </ul>
    </div>
    <div class="option-combo">
      <h2>Layout: </h2>
      <ul id="layouts" class="option-set clearfix" data-option-key="layoutMode">
        <li><a href="#masonry" data-option-value="masonry" class="selected">masonry</a></li>
        <li><a href="#fitRows" data-option-value="fitRows">fitRows</a></li>
        <li><a href="#straightDown" data-option-value="straightDown">straightDown</a></li>
      </ul>
    </div>
  </section>
  
  <div id="container" class="super-list variable-sizes clearfix">
    {% for elem_number in site.random_order limit:30 %}
      {% assign element = site.elements[elem_number] %}
      {% include element-partial.html %}
    {% endfor %}
    {% for feature in page.features %}
      <div class="element feature {{ feature.category }} width2 height2">
        <p class="number">{{ feature.number }}</p>
        <h3 class="symbol">{{ feature.symbol }}</h3>
        <h2 class="name">{{ feature.name }}</h2>
      </div>
    {% endfor %}
    <div class="link" data-number="5"><a href="jquery.isotope.min.js">Down&#8203;load jquery&#8203;.isotope&#8203;.min.js</a></div>
    <div class="link" data-number="13"><a href="http://meta.metafizzy.co/files/isotope-site.zip">Down&#8203;load this project</a></div> 
    <div class="link away" data-number="35"><a href="http://github.com/desandro/isotope">Isotope on GitHub</a></div>
  </div>

  <div id="sites"></div>
  
  
  <script src="{{ site.jquery_js }}"></script>
  <script src="{{ site.isotope_js }}"></script>
  <script>
    $(function(){
    
      var $container = $('#container');
    
      $container.isotope({
        masonry: {
          columnWidth: 120
        },
        sortBy: 'number',
        getSortData: {
          number: function( $elem ) {
            var number = $elem.hasClass('element') ? 
              $elem.find('.number').text() :
              $elem.attr('data-number');
            return parseInt( number, 10 );
          },
          alphabetical: function( $elem ) {
            var name = $elem.find('.name'),
                itemText = name.length ? name : $elem;
            return itemText.text();
          }
        }
      });
    
      {% include option-set-buttons.js %}

    
      // Sites using Isotope markup
      var $sites = $('#sites'),
          $sitesTitle = $('<h2 class="loading"><img src="http://i.imgur.com/qkKy8.gif" />Loading sites using Isotope</h2>'),
          $sitesList = $('<ul class="clearfix"></ul>');
        
      $sites.append( $sitesTitle ).append( $sitesList );

      $sitesList.isotope({
        layoutMode: 'cellsByRow',
        cellsByRow: {
          columnWidth: 290,
          rowHeight: 400
        }
      });
    
      var ajaxError = function(){
        $sitesTitle.removeClass('loading').addClass('error')
          .text('Could not load sites using Isotope :(');
      };
    
      // dynamically load sites using Isotope from Zootool
      $.getJSON('http://zootool.com/api/users/items/?username=desandro' +
          '&apikey=8b604e5d4841c2cd976241dd90d319d7' +
          '&tag=bestofisotope&callback=?')
        .error( ajaxError )
        .success(function( data ){

          // proceed only if we have data
          if ( !data || !data.length ) {
            ajaxError();
            return;
          }
          var items = [],
              item, datum;

          for ( var i=0, len = data.length; i < len; i++ ) {
            datum = data[i];
            item = '<li><a href="' + datum.url + '">'
              + '<img src="' + datum.image.replace('/l.', '/m.') + '" />'
              + '<b>' + datum.title + '</b>'
              + '</a></li>';
            items.push( item );
          }
        
          var $items = $( items.join('') )
            .addClass('example');
            
          // set random number for each item
          $items.each(function(){
            $(this).attr('data-number', ~~( Math.random() * 100 + 15 ));
          });
        
          $items.imagesLoaded(function(){
            $sitesTitle.removeClass('loading').text('Sites using Isotope');
            $container.append( $items );
            $items.each(function(){
              var $this = $(this),
                  itemHeight = Math.ceil( $this.height() / 120 ) * 120 - 10;
              $this.height( itemHeight );
            });
            $container.isotope( 'insert', $items );
          });
        
        });
    
    
    });
  </script>
