Animated Filtering & Sorting with the MixItUp 3 JS Library
Filtering and sorting parts of your website is a great way to organize content. Portfolios, albums, and blogs are just a few examples of things you might want to categorize. To achieve this, many JavaScript libraries can help. Two of the most popular ones are the MixItUp and Isotope libraries.
In this article, I’ll go over the basic features of MixItUp 3 (the latest release at the time of writing) and show you all the steps needed to take advantage of it in your projects. To better demonstrate how this library works, I’ve also created a demo, which I’ll refer to throughout the article.
Note: This article was updated in February 2017 to cover v3 of the MixItUp library
What is MixItUp 3?
As mentioned above, MixItUp 3 is a dependency-free, JavaScript library that allows you to filter and sort elements using CSS-based animations. Created by Patrick Kunka, it comes with a number of different customization options and detailed documentation. You can integrate it easily into your existing layouts. All that’s needed is to target the desired elements and the library will do the grunt work for you.
For non-commercial projects, you can use it for free. However, commercial projects require a license. More information is available on this page.
The library works in all modern browsers (including IE10+ with full functionality, and a fallback functional but with no animations in IE8+).
Now that we’ve seen what the library does, let’s see the required steps in order to use it.
Getting Started with MixItUp 3
To get started with MixItUp 3, you first have to include it in your projects. You can download it by visiting its GitHub page or by using a package manager like npm.
For our demo, we’ll use the first option. The required script will be placed before the closing </body>
tag, like this:
...
<script src="/path/to/mixitup.min.js"></script>
</body>
Let’s continue with the structure of our content.
Building the Container
First, we wrap the elements that we want to sort and filter in a container. The wrapped elements should each be given a common class name. In our case, the class name is mix-target
. The container will use this class to identify which are the target elements. Furthermore, we assign a unique ID to this container (mix-wrapper
). Later, we’ll target it to initialize an instance of MixItUp.
Here’s the HTML that demonstrates what I just described:
<ul class="courses" id="mix-wrapper">
<li class="mix-target">
<a href="#">Economics<span>(U)</span></a>
</li>
<li class="mix-target">
<a href="#">Pharmacology<span>(G)</span></a>
</li>
<!-- more list items here -->
</ul>
At this point, we’ve set up the basic structure of our elements. We’re now ready to see how the filtering and sorting work.
Filtering
We start by identifying the filter categories in our content. In this example, we’ll use some education-related categories: undergraduate
, graduate
, and phd
. Then, we add these as classes to the target elements.
Here’s the markup for the first two items:
<li class="mix-target undergraduate">
<a href="#">Economics<span>(U)</span></a>
</li>
<li class="mix-target graduate">
<a href="#">Pharmacology<span>(G)</span></a>
</li>
Next, we define the click handlers that will show the filter items. We’ll use <button>
elements to do this. We add the filter-btn
class and the data-filter
attribute to each of them. The value of the custom attribute should match the class names that have been applied to the target elements. The keywords all
and none
are also possible values.
Two of our filter buttons are shown below:
<button class="filter-btn" data-filter=".undergraduate">Undergraduate</button>
<button class="filter-btn" data-filter=".graduate">Graduate</button>
By default, when MixItUp first loads, it shows all the target elements. That means, the <button>
with the custom attribute data-filter="all"
is triggered. Moreover, the library applies the programs-filter-btn-active
class to this button. This allows us to style the selected filtering/sorting option to indicate that it was chosen.
Here’s how we’ll style it in our demo:
.programs button.programs-filter-btn-active,
.programs button.programs-sort-btn-active {
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5) inset, 0px 0px 1px transparent;
background: #3a9fbf;
color: white;
}
So far, only one filter control can be active at a time. But, let’s say that we want to filter based on multiple filter controls. For instance, in our case we should be able to see both the undergraduate and graduate programs at the same time. Happily, we can do this by taking advantage of the toggle controls. You can see our example with toggle handlers in this Codepen demo.
Let’s now continue with sorting.
Sorting
The first thing we have to do is to identify the attributes we want to sort by. In our project, these are the order
and year
attributes. As a next step, we use their names to apply custom attributes (data-order
and data-year
) to the target elements. The values of these custom attributes depend on the sort order we want to achieve.
The HTML for two items will look like this:
<li class="mix-target undergraduate" data-order="5" data-year="4">
<a href="#">Economics<span>(U)</span></a>
</li>
<li class="mix-target graduate" data-order="14" data-year="2">
<a href="#">Pharmacology<span>(G)</span></a>
</li>
At this point, we define <button>
elements as click handlers and add the sort-btn
class and the data-sort
attribute to each of them. The value of this attribute should use the following convention:
<button data-sort="order:asc">
So we have the attribute for sorting, then, as the value, we have an order type, followed by a colon along with either the “asc” or “desc” indicator.
This attribute also accepts as values the default
and random
keywords. Another interesting thing is that we can sort using multiple attributes at the same time.
Two of the sort buttons that are used in our example are shown below:
<button class="sort-btn" data-sort="order:asc">Ascending</button>
<button class="sort-btn" data-sort="year:desc order:desc">Descending <span class="multi">(Multi)</span></button>
When MixItUp first loads, the button with the attribute data-sort="default:asc"
is triggered. That said, the elements are sorted based on their DOM appearance. Similar to the default filter button, this button receives an active class (programs-sort-btn-active
).
Now that we’ve covered the basic features of the library, it’s time to see how we can initialize it.
Customization Options
To enable MixItUp 3’s functionality in our demo, we use the mixitup factory function and pass two parameters to it:
- A selector that represents our container
- and a configuration object that overrides the default behavior of MixItUp.
Here’s the code:
mixitup('#mix-wrapper', {
load: {
sort: 'order:asc' /* default:asc */
},
animation: {
effects: 'fade rotateZ(-180deg)', /* fade scale */
duration: 700 /* 600 */
},
classNames: {
block: 'programs', /* mixitup */
elementFilter: 'filter-btn', /* control */
elementSort: 'sort-btn' /* control */
},
selectors: {
target: '.mix-target' /* .mix */
}
});
Let’s have a closer look at our customizations:
- First, when the library loads, we change the default
active
sort button. - Next, we identify different animation effects for the target elements.
- Finally, we add custom classes to the target elements, filter, and sort buttons. So, for example, when a filter control becomes active, the
programs-filter-btn-active
class added to it instead of the generic defaultmixitup-control-active
class.
Note: The original default values are indicated in comments.
It’s worth mentioning that the mixitup
factory function returns an instance of MixItUp which we can manipulate by using its API methods.
You can view this example code in action in the full demo, which you can try below:
See the Pen MixItUp 3 JavaScript Library Demo by SitePoint (@SitePoint) on CodePen.
Conclusion
This article covers only the basics of using the MixItUp 3 library. There’s much more we could discuss, including the MixItUp Pagination and MixItUp MultiFilter extensions. I hope that at least the demo gave you an idea of how you could use it in an upcoming project.