Isotope (Masonry Layout)

Provides functionality to animate, filter and sort masonry layouts.

About the Plugin

Isotope facilitates filterable, sortable responsive masonry-style layouts.

Our script provides a wrapper to the Isotope library, exposing the most common functions and allowing all configuration to occur in HTML via markup and data-attributes.

Features
  • Simple masonry layout
  • Multiple masonry layouts per page
  • Filtering by click
  • Many filter groups per collection
  • Filtering by URL hash
  • Sorting criteria
  • Many sorter groups per collection
  • Reverse sorting

Initializing

The demo pages already include the following code. These steps are only necessary if you are building a page from scratch. Remove these references if you are not using this plugin to improve page load times.

  1. Include the library in your page
    • Copy the script tag below and paste in the foot of your page. Add this where you see the other library scripts. This line should be inserted after jquery.js and before theme.js.

      <!-- Isotope (masonry layouts and filtering) -->
      <script type="text/javascript" src="assets/js/isotope.pkgd.min.js"></script>

      Alternatively you may wish to load this resource from a CDN to potentially improve page load times.

      <!-- Isotope (masonry layouts and filtering) -->
      <script type="text/javascript" src="https://unpkg.com/isotope-layout@~3.0.6"></script>
  2. Load the initializer code in index.js
    • Declare the following import statement in js/mrare/index.js. This ensures that the initializer code is included in the theme.js bundle.

      import mrIsotope from './isotope';
    • Ensure the following line appears in the export object:

      export {
      mrIsotope,
      };

Basic Usage

A basic Isotope layout requires a <div> with data attribute data-isotope-collection.

Each direct child of the <div> should have the data-isotope-item attribute to be included as part of the collection.

The Isotope plugin will handle laying out each item with best fit. Isotope items can have any width.

Any other classes may be added to the Isotope items to style them how you wish.

<div class="col">
  <h2>Basic Example</h2>
  <div class="row" data-isotope-collection>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-10"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-30"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-20"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-20"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-30"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-10"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-20"></div>
    </div>
    <div data-isotope-item class="col-4">
      <div class="card bg-primary min-vh-10"></div>
    </div>
  </div>
</div>

Layout Mode

Add data-layout-mode to the data-isotope-collection element to specify one of the built-in layout modes provided by Isotope.

See the Isotope Layout Modes documentation for more.

Filters

Isotope collections can be filtered to show and hide grouped items matching a selected criteria. Filter groups contain the clickable elements used to filter the collection. An Isotope collection may have many filter groups linked to it.

To create a filter group, create an element with attribute data-isotope-filters. This can be placed anywhere on the page, and does not need to be placed adjacent to the Isotope layout.

When using filters, the data-isotope-collection and data-isotope-filters elements must have a matching data-isotope-id attribute. This is what links the two elements, allowing multiple Isotope collections per page, and multiple filter groups per collection.

Any element inside the data-isotope-filters element with attribute data-filter is considered a clickable filter.

Each data-isotope-item element requires a data-category attribute to specify which filter it belongs to. It will be shown when the corresponding filter is clicked, and hidden when a non-matching filter is clicked. An item may belong to two categories, as the filter uses a wildcard selector to match filters and categories.

Use data-filter="*" to show all items.

This basic example shows the required heirarchy:

<!-- First group of filters -->
<div data-isotope-filters data-isotope-id="matching_id_1">
  <a href="#" data-filter="*">All</a>
  <a href="#" data-filter="Blue">All</a>
  <a href="#" data-filter="Pink">All</a>
  <a href="#" data-filter="Navy">All</a>
</div>

<!-- Isotope collection -->
<div data-isotope-collection data-isotope-id="matching_id_1">
  <div data-isotope-item data-category="Blue">
  <div data-isotope-item data-category="Pink">
  <div data-isotope-item data-category="Navy">
  <div data-isotope-item data-category="Navy, Pink">
  <div data-isotope-item data-category="Pink, Blue">
</div>

<!-- Optional second group of filters linked to the same Isotope collection -->
<div data-isotope-filters data-isotope-id="matching_id_1">
  <a href="#" data-filter="*">All</a>
  <a href="#" data-filter="Blue">All</a>
  <a href="#" data-filter="Pink">All</a>
  <a href="#" data-filter="Navy">All</a>
  <a href="#" data-filter="Navy">All</a>
</div>

This is a full HTML example with a single filter group.

<div class="row justify-content-center">
  <div class="col">
    <h2>Filtering</h2>
    <div class="row">
      <div class="col">
        <ul data-isotope-filters data-isotope-id="isotope_1" class="nav mb-3">
          <li class="nav-item">
            <a href="#" class="nav-link active" data-filter="*">All</a>
          </li>
          <li class="nav-item">
            <a href="#" class="nav-link" data-filter="Blue">Blue</a>
          </li>
          <li class="nav-item">
            <a href="#" class="nav-link" data-filter="Pink">Pink</a>
          </li>
          <li class="nav-item">
            <a href="#" class="nav-link" data-filter="Navy">Navy</a>
          </li>
        </ul>
      </div>
    </div>
    <div class="row" data-isotope-collection data-isotope-id="isotope_1">
      <div data-isotope-item class="col-4" data-category="Blue">
        <div class="card shadow-3d bg-primary min-vh-30"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Blue">
        <div class="card shadow-3d bg-primary min-vh-10"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Navy">
        <div class="card shadow-3d bg-primary-3 min-vh-20"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Pink">
        <div class="card shadow-3d bg-primary-2 min-vh-10"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Blue">
        <div class="card shadow-3d bg-primary min-vh-10"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Navy">
        <div class="card shadow-3d bg-primary-3 min-vh-30"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Pink">
        <div class="card shadow-3d bg-primary-2 min-vh-20"></div>
      </div>
      <div data-isotope-item class="col-4" data-category="Navy">
        <div class="card shadow-3d bg-primary-3 min-vh-20"></div>
      </div>
    </div>
  </div>
</div>

Setting Default Filter

Add data-default-filter to the data-isotope-collection <div> with the value matching a category string.

Filtering By URL

Collections may be filtered by the hash in the page URL. For example, if you have an isotope collection on your page and a filter with data-filter="pink", you can automatically filter to pink on page load using #pink in your URL like so:

This will allow you to link to particular parts of your collection from anywhere in your site.

https://yourdomain.com/collections.html#pink

To disable this feature, add attribute data-ignore-hash="true" to the data-isotope-collection <div>.

Sorting

Isotope collections can be sorted according to set criteria. Sorting is controlled by clickable elements in a sorter group. An Isotope collection may have many sorter groups linked to it.

To create a sorter group, create an element with attribute data-isotope-sorters. This can be placed anywhere on the page, and does not need to be placed adjacent to the Isotope layout.

When using sorters, the data-isotope-collection and data-isotope-sorters elements must have a matching data-isotope-id attribute. This is what links the two elements, allowing multiple Isotope collections per page, and multiple sorter groups per collection.

Any element inside the data-isotope-sorters element with attribute data-sort and data-sort-selector is considered a clickable sorter.

Class active is applied to sorters when clicked, while being removed from all other sorters in the collection.

<ul data-isotope-sorters data-isotope-id="projects-1">
  <li>
    <span>Example Sorters</span>
  </li>
  <li data-sort="original-order" data-sort-selector="original-order">
    <span>Original Order</span>
  </li>
  <li data-sort="sortByStarRating" data-sort-selector="[data-star-rating] parseInt" data-sort-ascending="false">
    <span>Star Rating</span>
  </li>
  <li data-sort="sortByLikes" data-sort-selector=".num-likes parseInt" data-sort-ascending="false">
    <span>Likes</span>
  </li>
</ul>
Built-In Sort Methods

Isotope has two built-in sorting methods. To use these sorting methods, add the following required attributes to your button or link.

Required Attributes Description
data-sort="original-order" data-sort-selector="original-order" This sorts the Isotope items into the original order laid out in HTML.
data-sort="random" data-sort-selector="random" Randomizes the order of the items with each click.
Custom Sort Methods

Isotope items can be sorted according to text or data held within the markup of each item. Custom sort methods are defined by the clickable elements in the data-isotope-sorters <div>.

Each sort method requires the following two attributes:

  • A unique id for the sort method, defined by the data-sort attribute. Eg. "sortByName", or "sortByRanking".
  • A source for the data defined by the data-sort-selector attribute. This selector points to an element or attribute which each Isotope item has in common.
Sorting data can be taken from the following sources
Source data-sort-selector
Text of child element of Isotope items A selector which identifies the item. Eg. "span" or ".likes-count"
Text of child element of Isotope items parsed as integer A selector which identifies the item with the addition of parseInt directive. Eg. "span parseInt" or ".likes-count parseInt"
Text of child element of Isotope items parsed as float A selector which identifies the item with the addition of parseFloat directive. Eg. "span parseFloat" or ".longitude parseFloat"
Plain attribute on an Isotope item "[src]", "[href]", "[alt]" etc.
Data attribute on Isotope item "[data-category]", "[data-likes]", "[data-index]", "[data-ranking]" etc.

Note: If you are familiar with the Isotope plugin, the data-sort value is used internally as each key in Isotope's getSortData configuration option. See documentation for more detail.

Examples

In the following examples, the items will be sorted in ascending order, which is the default. See Sort Ascending / Descending below.

data-sort-selector=".name"  // Sort by text of child element with class 'name'.
data-sort-selector=".symbol"  // Sort by text of child element with class 'symbol'.
data-sort-selector="[data-category]" // Sort by alphabetic text of the `data-category` attribute.
data-sort-selector=".number parseInt" // Sort by text of child element with class 'number', parsed as an integer.
data-sort-selector=".weight parseFloat" // Sort by text of element with class 'weight', parsed as a float.

For more examples, please see the Isotope Documentation.

Setting Default Sort

Add data-default-sort to the data-isotope-collection <div> with the value containing the data-sort ID of your preferred default sort method.

If not specified, the default sort method will be original-order.

Example
<div data-isotope-sorters data-isotope-id="isotope_1">
  <li data-sort="original-order" data-sort-selector="original-order">
    <span>Original Order</span>
  </li>
  <li data-sort="sortByStarRating" data-sort-selector="[data-star-rating] parseFloat" data-sort-ascending="false">
    <span>Star Rating</span>
  </li>
  <li data-sort="sortByLikes" data-sort-selector=".num-likes parseInt" data-sort-ascending="false">
    <span>Likes</span>
  </li>
</div>
<div class="row" data-isotope-collection data-isotope-id="isotope_1" data-default-sort="sortByLikes">
  <div data-isotope-item class="col-4" data-category="Blue" data-star-rating=-"4.5">
    <div class="card shadow-3d bg-primary min-vh-30">
      <span class="num-likes">125</span>
    </div>
  </div>
  <div data-isotope-item class="col-4" data-category="Blue" data-star-rating="3.9">
    <div class="card shadow-3d bg-primary min-vh-10">
      <span class="num-likes">98</span>
    </div>
  </div>
</div>

Sort Ascending / Descending

By default, custom sort methods will sort in ascending order (from lower to higher, a-z). To reverse the sort direction, add the attribute data-sort-ascending="false" to your custom sort method.

TIP: To create sort options, simply create two sorting methods like so:

<ul data-isotope-sorters data-isotope-id="projects-1">
  <li data-sort="starRatingHighLow" data-sort-selector="[data-star-rating] parseFloat" data-sort-ascending="false">
    <span>Star Rating (High to Low)</span>
  </li>
  <li data-sort="starRatingLowHigh" data-sort-selector="[data-star-rating] parseFloat">
    <span>Star Rating (Low to High)</span>
  </li>
</ul>

Advanced Sorting

You may wish to sort by two criteria at the same time, such as "Date then Likes" or "Ranking then Price".

For a sorter to use two criteria, it must have the following three attributes:

  • data-sort - ID for this sorting method.
  • data-primary-sort - first priority.
  • data-secondary-sort - second priority.

The value of these attributes must be sorter IDs defined in data-sort on other sorters in the collection.

Example
<ul data-isotope-sorters data-isotope-id="projects-1">
  <li data-sort="starRatingHighLow" data-sort-selector="[data-star-rating] parseFloat" data-sort-ascending="false">
    <span>Sort By Star Rating (High to Low)</span>
  </li>
  <li data-sort="priceLowHigh" data-sort-selector="span.price parseFloat">
    <span>Sort By Price (Low to High)</span>
  </li>
  <li data-sort="ratingThenPrice" data-primary-sort="starRatingHighLow" data-secondary-sort="priceLowHigh">
    <span>Sort By Star Rating then Price</span>
  </li>
</ul>

Full Example

This example shows how to use various filters, various sorters, advanced sorters, reverse "show all"

<style>
  .active { font-weight: bold; }
  ul { list-style: none; }
  [data-isotope-filters] li, [data-isotope-sorters] li { cursor: pointer; }
  .num-likes { font-style: italic }
</style>

<section>
  <div class="container">
    <div class="row">
      <div class="col text-center">

        <!-- Filters 1 -->
        <ul data-isotope-filters data-isotope-id="full-example">
          <li>
            <span>Filter Group 1</span>
          </li>
          <li data-filter="*">
            <span>All</span>
          </li>
          <li data-filter="widgets">
            <span>Widgets</span>
          </li>
          <li data-filter="gadgets">
            <span>Gadgets</span>
          </li>
          <li data-filter="doosies">
            <span>Doosies</span>
          </li>
          <li data-filter="trinkets">
            <span>Trinkets</span>
          </li>
        </ul>

        <hr>

        <!-- Sorters 1 -->
        <ul data-isotope-sorters data-isotope-id="full-example">
          <li>
            <span>Sorter Group 1</span>
          </li>
          <li data-sort="original-order" data-sort-selector="original-order">
            <span>Original Order</span>
          </li>
          <li data-sort="starRating" data-sort-selector="[data-star-rating] parseInt" data-sort-ascending="false">
            <span>Star Rating</span>
          </li>
          <li data-sort="likes" data-sort-selector=".num-likes parseInt" data-sort-ascending="false">
            <span>Likes</span>
          </li>
        </ul>
      </div>
    </div>

    <hr>

    <div class="row">
      <div class="col text-center">

        <!-- Isotope Collection -->
        <div class="row" data-isotope-collection data-isotope-id="full-example" data-default-sort="starRating">
          <div class="col-3" data-isotope-item data-category="widgets" data-star-rating="3">
            <img src="https://picsum.photos/200/300/?random&0" alt="widgets,trinkets">
            <span>Widgets</span>
            <span class="star-rating">(Rating: 3)</span>
            <span class="num-likes">463</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="widgets,doosies" data-star-rating="4">
            <img src="https://picsum.photos/200/300/?random&00" alt="image">
            <span>Widgets, Doosies</span>
            <span class="star-rating">(Rating: 4)</span>
            <span class="num-likes">964</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="widgets" data-star-rating="8">
            <img src="https://picsum.photos/200/300/?random&1" alt="image">
            <span>Widgets</span>
            <span class="star-rating">(Rating: 8)</span>
            <span class="num-likes">367</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="gadgets" data-star-rating="6">
            <img src="https://picsum.photos/200/300/?random&2" alt="image">
            <span>Gadgets</span>
            <span class="star-rating">(Rating: 6)</span>
            <span class="num-likes">27</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="gadgets,doosies" data-star-rating="3">
            <img src="https://picsum.photos/200/300/?random&3" alt="image">
            <span>Gadgets, Doosies</span>
            <span class="star-rating">(Rating: 3)</span>
            <span class="num-likes">3557</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="gadgets" data-star-rating="1">
            <img src="https://picsum.photos/200/300/?random&4" alt="image">
            <span>Gadgets</span>
            <span class="star-rating">(Rating: 1)</span>
            <span class="num-likes">563</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="trinkets" data-star-rating="5">
            <img src="https://picsum.photos/200/300/?random&5" alt="image">
            <span>Trinkets</span>
            <span class="star-rating">(Rating: 5)</span>
            <span class="num-likes">95</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="trinkets,gadgets" data-star-rating="4">
            <img src="https://picsum.photos/200/300/?random&6" alt="image">
            <span>Trinkets, Gadgets</span>
            <span class="star-rating">(Rating: 4)</span>
            <span class="num-likes">158</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="doosies" data-star-rating="2">
            <img src="https://picsum.photos/200/300/?random&7" alt="image">
            <span>Doosies</span>
            <span class="star-rating">(Rating: 2)</span>
            <span class="num-likes">582</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="doosies,trinkets" data-star-rating="9">
            <img src="https://picsum.photos/200/300/?random&8" alt="image">
            <span>Doosies, Trinkets</span>
            <span class="star-rating">(Rating: 9)</span>
            <span class="num-likes">113</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="doosies" data-star-rating="2">
            <img src="https://picsum.photos/200/300/?random&9" alt="image">
            <span>Doosies</span>
            <span class="star-rating">(Rating: 2)</span>
            <span class="num-likes">784</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="widgets" data-star-rating="8">
            <img src="https://picsum.photos/200/300/?random&10" alt="image">
            <span>Widgets</span>
            <span class="star-rating">(Rating: 8)</span>
            <span class="num-likes">35</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="trinkets" data-star-rating="3">
            <img src="https://picsum.photos/200/300/?random&11" alt="image">
            <span>Trinkets</span>
            <span class="star-rating">(Rating: 3)</span>
            <span class="num-likes">10</span> <span>Likes</span>
          </div>

          <div class="col-3" data-isotope-item data-category="trinkets" data-star-rating="7">
            <img src="https://picsum.photos/200/300/?random&12" alt="image">
            <span>Trinkets</span>
            <span class="star-rating">(Rating: 7)</span>
            <span class="num-likes">2</span> <span>Likes</span>
          </div>

        </div>
        <!-- END Isotope Collection -->

      </div>
    </div>

    <div class="row">
      <div class="col text-center">

        <!-- Sorters 2 -->
        <ul data-isotope-sorters data-isotope-id="full-example">
          <li>
            <span>Sorter Group 2</span>
          </li>
          <li data-sort="original-order" data-sort-selector="original-order">
            <span>Original Order</span>
          </li>
          <li data-sort="starRating" data-sort-selector="[data-star-rating] parseInt" data-sort-ascending="false">
            <span>Star Rating</span>
          </li>
          <li data-sort="likes" data-sort-selector=".num-likes parseInt" data-sort-ascending="false">
            <span>Likes</span>
          </li>
        </ul>

        <hr>

        <!-- Filters 2 -->
        <ul data-isotope-filters data-isotope-id="full-example">
          <li>
            <span>Filter Group 2</span>
          </li>
          <li data-filter="*">
            <span>All</span>
          </li>
          <li data-filter="widgets">
            <span>Widgets</span>
          </li>
          <li data-filter="gadgets">
            <span>Gadgets</span>
          </li>
          <li data-filter="doosies">
            <span>Doosies</span>
          </li>
          <li data-filter="trinkets">
            <span>Trinkets</span>
          </li>
        </ul>
      </div>
    </div>
  </div>
</section>