Coding a Minimalist Portfolio Layout with Dynamically Sorted Projects

Freelancers and designers are often looking for ways to spice up a typical portfolio layout. You want to show off your most recent works to potential clients, while also offering a quick way to learn about your talents and get in contact. Single-page layouts are great if you have the design capability. But there are also other unique types of portfolio user interfaces which are stunning as well.

In this tutorial I want to demonstrate how we can build a dynamic filtered portfolio list using jQuery. To speed up the development process we can use a jQuery plugin Quicksand to help with the sorting animations. This is a lucrative method for people who build various types of products and want to showcase their work together in one place. You could also link the portfolio images to display embedded text or photobox modal windows.

Live Demo PreviewDownload Source Code

Getting Started

First create a new directory for the project code and download the latest quicksand plugin off Github. The master repo will always contain the most recently updated version, as new commits are pushed by other coders o the original developer. Now create a new blank index.html file which will be the container for our webpage.

I am going to use the typical HTML5 doctype with a few 3rd party resources. Aside from the Quicksand plugin we also need a copy of jQuery and also the html5shiv library isn’t a bad idea either. For sprucing up the typography I’ll include a Google Webfont named Kite One. This will be used in the sorting options menu.

<!doctype html>  <html lang="en-US">  <head>    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">    <title>Dynamically Sorted Portfolio Demo</title>    <meta name="author" content="Jake Rocheleau">    <link rel="stylesheet" type="text/css" href="styles.css">    <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Kite+One">    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>    <script type="text/javascript" charset="utf-8" src="jquery.quicksand.js"></script>    <script type="text/javascript" charset="utf-8" src="sorting.js"></script>  <!--[if lt IE 9]>    <script type="text/javascript" src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>  <![endif]-->  </head>

Notice that aside from all these remote scripts I have also included two more of my own files. The first stylesheet styles.css will contain all the CSS details for our layout. Then sorting.js has some basic jQuery we need to perform as the user clicks each link. You have the choice to include this code right into your HTML page using script tags, but I feel using a separate file keeps it all cleaner.

Building the Layout

Let’s move down into the HTML body code where all the content is placed. I won’t copy over everything since much of the portfolio listing is redundant. But it is crucial to understand the different attributes we are setting and how these affect Quicksand.

<div class="sort" id="sort">  	<span class="label">Filter By:</span> <a href="#" class="all selected">All</a> <a href="#" class="web">Web</a> <a href="#" class="ios">iOS</a> <a href="#" class="print">Print</a>  </div>    <ul class="portfolio clearfix">    <li data-id="id-1" class="ios"><a href="http://dribbble.com/shots/815728-Coffeemania-iphone-app" target="_blank"><img src="images/ios-app-ui-01.png" class="portimg"></a></li>    <li data-id="id-2" class="print"><a href="http://dribbble.com/shots/816387-Shapeways-Gift-Card" target="_blank"><img src="images/print-design-cards.png" class="portimg"></a></li>  </ul>

Inside the wrapper class we have two main child elements. First the div with a class .sort which holds all four of our sorting links. The class names are relative to how I have labeled each of the portfolio items. The link with an added class of .selected will appear to be the current filter.

The .portfolio class is actually applied directly to the <ul> element. Inside you will find each list item is using the data-id HTML5 attribute syntax in the format of id-#. These ID numbers are required for Quicksand to operate properly by hiding/showing individual items.

Also you should notice how each list item is given a matching class related to a link sorting option. I haven’t used any of these classes for CSS styles, so I decided we can sort the portfolio items using this class value. However if you need to keep your classes separate you can use another attribute such as data-name to hold your sorting options.

Custom CSS Page Styles

Moving inside the stylesheet document I have included a slightly updated version to the more generic Eric Meyer’s reset. What is really important here is how I am styling the portfolio items as they are floating inside the unordered list. But first we can take a quick peek at the filter links.

/* main page layout */  #w { display: block; min-width: 850px; max-width: 1150px; margin: 0 auto; padding: 0 15px; padding-top: 45px; }    /* sorting and filtering */  .sort { display: block; font-family: 'Kite One', Arial, sans-serif; font-size: 1.4em; line-height: 0.9em; color: #444; }    .sort .label { margin-right: 11px; }    .sort a { margin-right: 4px; padding: 0px 3px; }  .sort a:hover { color: #989caa; text-decoration: none; border-bottom: 1px dotted #989caa; }    .sort a.selected { color: #85878f; border-bottom: 1px solid #85878f; }

You will notice the .sort menu is where I’m applying this custom Google font into the document. Just using very basic grey/dark grey colors and a border to denote selected items. You could ultimately place this sorting menu anywhere in your layout and still have Quicksand working properly.

/* portfolio items */  .portfolio { display: block; margin-bottom: 10px; padding-top: 20px; width: 100%; }    .portfolio li {     float: left;     margin-right: 18px;     margin-bottom: 1.55em;    -webkit-box-shadow: 1px 2px 3px rgba(0,0,0,0.45);    -moz-box-shadow: 1px 2px 3px rgba(0,0,0,0.45);    box-shadow: 1px 2px 3px rgba(0,0,0,0.45);  }  .portfolio li a {     display: block;     padding: 4px;     background: #fff;     border: 1px solid #ccc;     -webkit-transition: all 0.35s linear;     -moz-transition: all 0.35s linear;     -o-transition: all 0.35s linear;    transition: all 0.35s linear;  }  .portfolio li a:hover { opacity: 0.65; }

On the container .portfolio I have added a display: block; property so the whole element takes up the full width of our page. But the problem is that list items are floating left which removes them from the typical page flow. This means as you would resize the links they would all float over to the left before appearing back into a grid.

The way we fix this is by adding width: 100%; onto the portfolio container. Now it will stay the same width as the page no matter if the whole list is empty or floating. We also use some nice CSS3 transitions on the anchor hover to fade out opacity.

Working with Quicksand jQuery

Let’s finally move onto the JavaScript side where we setup the portfolio filtering. I want to first create the click event listener tied to all the anchor links inside our sort container. Then we need to disable the HREF value and instead perform our custom sorting method.

$(document).ready(function(){    var pclone = $(".portfolio").clone();      $("#sort a").on("click", function(e){      e.preventDefault();      var sorttype = $(this).attr("class");

The var pclone is a portfolio clone variable which contains a cloned jQuery object. We use this to quickly access the full list of portfolio items instead of messing with the already-existing DOM elements. Also I am setting another variable sorttype which checks the current anchor links’ class value. This is the value we need to filter into the portfolio listing and find similar matches.

// determine if another link is selected  if(!$(this).hasClass("selected")) {    $("#sort a").removeClass("selected");    $(this).addClass("selected");  }    // check filter sort type  if(sorttype == "all") {    var filterselect = pclone.find("li");  } else {    var filterselect = pclone.find("li[class="+sorttype+"]");  }

The final piece of our script is split into two logic statements. First we need to check if any other anchor links already have the class .selected. If this is true then we run .removeClass(“selected”) on all the sorting anchor links to make sure we have nothing selected. Then set a new selected class to the recently clicked element.

The 2nd block of code is checking against our current sorttype variable. If we are calling all the elements back into view then we only need to filter for regular list items(<li>). Otherwise we need to find only list items with a matching class value. Either way we get a new variable filterselect which is passed into our Quicksand method call.

$(".portfolio").quicksand(filterselect,   {    adjustHeight: 'auto',    duration: 550  }, function() {     // callback function  });

This brief function is all we need to run the final sorting command. All the other logic statements are important to determine which type of content is being filtered. Using the adjustHeight parameter will keep duplicate content from taking up excess page space. Also the duration may be edited to any value that you like, formatted in milliseconds. The callback function should contain any codes you want to run after the filtering is complete, but you can leave it blank too.

Have a look at my demo example below to see how this all comes together. I configured this demo using most of the default settings to make it easier to follow. But have a look at the Quicksand documentation to better understand some of the extra parameters. For example, if you include the jQuery easing plugin you can alter the type of animation effect to any other provided options – or even create your own!

Live Demo Preview – Download Source Code

Final Thoughts

If you play around with the Quicksand demo page you can learn a lot about how the plugin operates. All of the CSS styles and positioning can be determined remotely on your own layout. It does take a bit of tinkering to get all the bugs worked out, but the final result is fantastic.

I hope this tutorial can prove useful to any developers looking to create a sorted webpage list. The dynamic animations are aesthetically beautiful and offer a rich user experience. Plus the system utilizes HTML5 attributes which are still unique to many web developers. If you have any further thoughts or questions on the tutorial drop a comment in the discussion area.

DesignWoop Newsletter

Sign up to the DW newsletter, occasionally we send design & development related freebies, offers and exclusive deals.

9 Comments

Comments are now closed.