How to Build a Filterable Animated Portfolio Layout

Most web designers are familiar with the trend of auto-sorting filtered portfolios.

Creative artists who work in multiple disciplines may split up into different topics like illustrations, typography, print work, and other similar ideas. Years ago this would require a custom script but nowadays CSS3 and jQuery have expedited the process.

In this tutorial I want to introduce you to a powerful library called MixItUp. My demo is geared towards a typical designer or developer who needs a set of categorical topics. However you can even sort works by secondary attributes like the project's date, the contracting company, or anything else you might think is pertinent info!

filterable animated portfolio layout

Live Demo - Download Source Code

Getting Started

One of the best things about this plugin is that it's completely open source for commercial and non-commercial use. Include this on your next web project, premium WordPress theme, or even on your own personal website. To get started download a local copy of jQuery along with a copy of the MixItUp library.

These are the only two required resources we need to get everything running. I've also setup my own related styles.css stylesheet for constructing the webpage itself. This is meant to be a fully-responsive layout which can adapt down to mobile smartphone displays.

1
2
3
4
5
6
7
8
9
10
11
12
13
<!doctype html>
<html lang="en-US">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>Filterable Portfolio using MixItUp - TemplateMonster Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="https://www.templatemonster.com/favicon.ico">
  <link rel="icon" href="https://www.templatemonster.com/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="css/styles.css">
  <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  <script type="text/javascript" src="js/jquery.mixitup.min.js"></script>
</head>

The actual process of creating the body content may get a little confusing. The setup guide you'll find on the MixItUp website is okay, but the language is somewhat vague in places. There are 3 main areas you can utilize with possible extensions based on your needs:

  1. Grid - contains all your portfolio items in an unordered list. These can be images, blocks of text, or anything that will cascade naturally into a grid-like format.
  2. Filters - little controls which appear at the top of the page for categorizing each grid item. Some grid items may use more than one filter, like a web design that also includes Internet marketing.
  3. Sorting - optional controls for rearranging the sort type of your items from ascending to descending, or vice versa.

Building the Inner Page

For my demo we can simplify the process by ignoring the sort order. By default your items will be sorted in the exact order that they're found in the HTML. How they are coded into the list will determine where they show up, even with filters applied.

1
2
3
4
5
6
7
<ul id="filter-list" class="clearfix">
  <li class="filter" data-filter="all">All</li>
  <li class="filter" data-filter="webdesign">Web Design</li>
  <li class="filter" data-filter="appicon">App Icons</li>
  <li class="filter" data-filter="iosappui">iOS App UI</li>
  <li class="filter" data-filter="illustration">Illustration</li>
</ul><!-- @end #filter-list -->

This area can be found just after my opening wrapper div. It contains all the different categories a user may select to filter between the portfolio items. The plugin looks for an element with the class of .filter so it's easiest to just keep this formatting. This can be changed using the filterSelector option later in JavaScript.

You'll notice that none of these list items include anchor links. Basically we don't need them because an HREF value is pointless; The code will run whenever a user clicks an element with the class .filter. So in this case I re-styled the list items to appear as links using a hand cursor along with hover/active states.

1
2
3
4
5
6
7
8
9
10
<ul id="portfolio">
  <li class="item webdesign"></li>
  <li class="item illustration"></li>
  <li class="item appicon"><a href="http://dribbble.com/shots/1337536-App-Icon"></a></li>
  <li class="item iosappui"></li>
  <li class="item iosappui"></li>
  <li class="item illustration"><a href="http://dribbble.com/shots/1338582-Bold-As-Love"></a></li>
  <li class="item webdesign"></li>
  <li class="item iosappui"><a href="http://dribbble.com/shots/1221413-Chat-app"></a></li>
</ul><!-- @end #portfolio -->

Just below the filters you find these portfolio items in a simple unordered list. We need some type of ID which gets called as the jQuery selector to run this plugin. I've chosen #portfolio and you can do anything that makes sense for your website. Also notice each list item needs a special class to be recognized - I've customized this class to be .item.

However MixItUp will default to using the class .mix, I simply updated the targetSelector in jQuery. But it doesn't actually matter because class names will never be seen on the frontend. So it's more about personal preference in this case.

What really matters is the secondary class(es) which all relate to a category in your filters list. All of my items use a single category, but remember that you can include 2 or even 3+ different category classes on each item. The internal HTML really doesn't matter too much as long as each item remains within the DOM, not being absolutely/relatively positioned.

Basic CSS Styles

The jQuery command is fairly basic so before we move onto that, I want to first explain some of my stylesheet properties. Let's look over the filters list first:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/** filters list **/
#filter-list {
  display: block;
  width: 100%;
  text-align: center;
  margin-bottom: 25px;
}
 
#filter-list li {
  display: inline-block;
  width: auto;
  padding: 6px 10px;
  margin-right: 15px;
  font-size: 1.2em;
  cursor: pointer;
  text-shadow: 1px 1px 0 #fff;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
}
#filter-list li:hover {
  background: #e7e2eb;
}
#filter-list li.active {
  font-weight: bold;
  background: #d8c5e7;
}

The whole list is kept in a center block with individual list items displaying next to each other. The hover effect uses a pseudo class, but active uses a full selector class .active. This is because MixItUp will automatically apply the active class onto whichever filter is currently being used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/** portfolio list **/
#portfolio {
  display: block;
  width: 100%;
  padding: 0 12px;
  margin-bottom: 35px;
  text-align: center;
}
 
#portfolio .item {
  display: none;
  opacity: 0;
  width: 40%;
  vertical-align: top;
  margin-bottom: 25px;
  margin-right: 20px;
  color: #fff;
  font-size: 30px;
  text-align: center;
  -moz-box-sizing: border-box;
}
#portfolio .item a {
  display: inline-block;
  max-width: 100%;
  text-decoration: none;
  background: #fff;

}
#portfolio .item img {
  padding: 3px;
  max-width: 100%;
  -webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.55);
  -moz-box-shadow: 0 1px 4px rgba(0,0,0,0.55);
  box-shadow: 0 1px 4px rgba(0,0,0,0.55);
}

Each portfolio item must include the display:none and opacity:0 properties when first loading on the page. Then MixItUp takes over and checks which filter is being applied - by default it uses "all" so everything will fade back into view. These properties are both important so we don't have jumpy animations during filter transitions. Also since these are responsive the items should be stretchy on resize, and not break down to the next line. max-width:100% is the key on both of my images and the anchor links.

The responsive codes are also based on really simple media queries. Whenever something is about to hit an edge I've broken down the elements to appear smaller - first the title followed by the internal body content.

1
2
3
4
5
6
7
8
9
10
11
12
13
/** media queries **/
@media screen and (max-width: 720px) {
  h1 { font-size: 2.7em; }
}
 
@media screen and (max-width: 500px) {
  h1 { font-size: 2.0em; }
  #filter-list { padding: 0 18px; }
  #filter-list li { display: block; margin-bottom: 3px; }
  
  #portfolio { margin-bottom: 20px; }
  #portfolio .item { width: 100%; margin-bottom: 12px; margin-right: 0; }
}

In responsive mode the filter items will display as full block elements taking over 100% width. Same with the portfolio elements but they won't stretch beyond the actual image's width/height value. This is also a good opportunity to rearrange padding and margins to better suit the compact design.

Initializing jQuery

Finally at the very bottom of the page you will notice a small JavaScript block. My example is small because I've only changed a couple options. You actually don't need to use any options, but they provide a more enhanced interface. You can read a whole lot more about these customizable parameters from the MixItUp documentation page.

1
2
3
4
5
6
$(function(){
  $('#portfolio').mixitup({
    targetSelector: '.item',
    transitionSpeed: 450
  });
});

If you remember from earlier I mentioned that I changed the portfolio item class from .mix to .item. This is quicker in my mind because each internal portfolio graphic is an item, so the name feels easier to read through in HTML.

transitionSpeed is the only other option I customized and it's set to a default of 600ms. I like the quicker animation because sometimes it will lag on smartphones, which can get annoying. It also helps with the responsive design so users aren't left waiting for the animation to finish before scrolling or swiping down the page.

filterable animated portfolio layout

Live Demo - Download Source Code

Closing

There are other plugins out there to replicate these same filtering effects. But after trying many solutions I have to conclude that MixItUp as the easiest choice. There are so many additional parameters(not required) and developers have more control to write their own callback functions. Feel free to download a copy of my tutorial codes and try playing around with these extra options to see what else is possible.


Jake Rocheleau

First it was design, then writing, and now affiliate marketing. Over a period of 6-7 years he wrote a lot of content for many websites. You can reach Jake on Twitter.

Get more to your email

Subscribe to our newsletter and access exclusive content and offers available only to MonsterPost subscribers.

From was successfully send!
Server error. Please, try again later.

Leave a Reply