Isotope is a very powerful jQuery plugin that allows you to create sortable, filterable (I’m sure that’s a word) masonry layouts (although you can have other layouts as well). Isotope is free for personal use (a commercial license costs $25, and an organizational license $90).
In this tutorial I will show how to add the Isotope code and scripts to a template. In my example, I will use the categories to filter a list of posts.
Update: I wrote a part 2 for this tutorial that shows how to use one category’s subcategories to filter posts.
- Download the script from the Isotope repository, and upload it to your theme’s folder (for example /js/libs/jquery.isotope.min.js)
- Add a list of categories that will serve as filters (following the filtering instructions in istotope):
<ul id="filters">
<li><a href="#" data-filter="*" class="selected">Everything</a></li>
<?php
$terms = get_terms("category"); // get all categories, but you can use any taxonomy
$count = count($terms); //How many are they?
if ( $count > 0 ){ //If there are more than 0 terms
foreach ( $terms as $term ) { //for each term:
echo "<li><a href='#' data-filter='.".$term->slug."'>" . $term->name . "</a></li>\n";
//create a list item with the current term slug for sorting, and name for label
}
}
?>
</ul>
- Make a custom loop to load a bunch of blog post. Each blog posts must share a class (in my case, I used ‘item’), and additional classes to filter (from the list of categories from Setp 2):
<?php $the_query = new WP_Query( 'posts_per_page=50' ); //Check the WP_Query docs to see how you can limit which posts to display ?>
<?php if ( $the_query->have_posts() ) : ?>
<div id="isotope-list">
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
$termsArray = get_the_terms( $post->ID, "category" ); //Get the terms for this particular item
$termsString = ""; //initialize the string that will contain the terms
foreach ( $termsArray as $term ) { // for each term
$termsString .= $term->slug.' '; //create a string that has all the slugs
}
?>
<div class="<?php echo $termsString; ?> item"> <?php // 'item' is used as an identifier (see Setp 5, line 6) ?>
<h3><?php the_title(); ?></h3>
<?php if ( has_post_thumbnail() ) {
the_post_thumbnail();
} ?>
</div> <!-- end item -->
<?php endwhile; ?>
</div> <!-- end isotope-list -->
<?php endif; ?>
- Go check. At this point your page should have a list with all your categories, and a bunch of posts. View the page source to make sure the blog posts have the proper classes (‘item’, plus all the categories it belongs to).
- Create a file with the necessary JavaScript to launch and set up Isotope, and place it in your theme folder (for example, /js/isotope.js):
jQuery(function ($) {
var $container = $('#isotope-list'); //The ID for the list with all the blog posts
$container.isotope({ //Isotope options, 'item' matches the class in the PHP
itemSelector : '.item',
layoutMode : 'masonry'
});
//Add the class selected to the item that is clicked, and remove from the others
var $optionSets = $('#filters'),
$optionLinks = $optionSets.find('a');
$optionLinks.click(function(){
var $this = $(this);
// don't proceed if already selected
if ( $this.hasClass('selected') ) {
return false;
}
var $optionSet = $this.parents('#filters');
$optionSets.find('.selected').removeClass('selected');
$this.addClass('selected');
//When an item is clicked, sort the items.
var selector = $(this).attr('data-filter');
$container.isotope({ filter: selector });
return false;
});
});
- There is some optional, but recommended CSS that you should add to animate the filtering. Place a CSS file with the code in your theme folder (for example, /css/isotope.css). Feel free to add additional styles to make your posts look nice:
/* Start: Recommended Isotope styles */
/**** Isotope Filtering ****/
.isotope-item {
z-index: 2;
}
.isotope-hidden.isotope-item {
pointer-events: none;
z-index: 1;
}
/**** Isotope CSS3 transitions ****/
.isotope,
.isotope .isotope-item {
-webkit-transition-duration: 0.8s;
-moz-transition-duration: 0.8s;
-ms-transition-duration: 0.8s;
-o-transition-duration: 0.8s;
transition-duration: 0.8s;
}
.isotope {
-webkit-transition-property: height, width;
-moz-transition-property: height, width;
-ms-transition-property: height, width;
-o-transition-property: height, width;
transition-property: height, width;
}
.isotope .isotope-item {
-webkit-transition-property: -webkit-transform, opacity;
-moz-transition-property: -moz-transform, opacity;
-ms-transition-property: -ms-transform, opacity;
-o-transition-property: -o-transform, opacity;
transition-property: transform, opacity;
}
/**** disabling Isotope CSS3 transitions ****/
.isotope.no-transition,
.isotope.no-transition .isotope-item,
.isotope .isotope-item.no-transition {
-webkit-transition-duration: 0s;
-moz-transition-duration: 0s;
-ms-transition-duration: 0s;
-o-transition-duration: 0s;
transition-duration: 0s;
}
/* End: Recommended Isotope styles */
- In functions.php, load the scripts and CSS:
function add_isotope() {
wp_register_script( 'isotope', get_template_directory_uri().'/js/libs/jquery.isotope.min.js', array('jquery'), true );
wp_register_script( 'isotope-init', get_template_directory_uri().'/js/isotope.js', array('jquery', 'isotope'), true );
wp_register_style( 'isotope-css', get_stylesheet_directory_uri() . '/css/isotope.css' );
wp_enqueue_script('isotope-init');
wp_enqueue_style('isotope-css');
}
add_action( 'wp_enqueue_scripts', 'add_isotope' );
That’s it!
An excellent step by step instruction o ho to integrate this jQuery plugin. I will be using this on my own WordPress layouts.
This is awesome. Searched everywhere for something that would work. Thank you very much.
Do you know how you would modify the code or CSS so that the active filter appeared as a different color?
Nevermind, figured that out 🙂 Modified the .selected class. Nice!
Thank you for this tutorial. This has to be the best post I have seen on integrating Isotope and WordPress.
Thank you! Really helpful 🙂
Great tutorial – works like a charm in Firefox – but I can’t get it to work in Safari, Chrome or Opera…. Do you have a solution for that.
Hi Kent,
It should work in all browsers. Are you developing locally? That could be an issue. If not, send me the URL, and I’ll take a look.
Thanks for the article Alicia. The code you supplied for the filter/s, identifiers and the javascript got my Isotope based page up and running really fast. Thank you!
How could I use this with woocommerce using the subcategories as filters on the main category page.
I’m not that familiar with woocommerce, but I just wrote a second tutorial that shows how to filter posts that belong to one category by tis subcategories.
Hi, thanks for this post, it’s amazing. It’s exactly what I’v been looking for. Would yo be able to tell me how to target custom post types with custom fields though? Thanks again. x
Now a days WordPress is the powerful CMS for website design & development. we can maximum utilize it by using this type of plug in.
Such a great explanation on how to integrate plugin thanks for posting!Like to get more new updates from you thanks!
Thanks for taking the time to put this together, great step by step guide! Much appreciated!
Well written tutorial !!
Alicia Ramirez, good work, I believe, people will be forever in need of Isotope wordpress integration tutorial.
Thank you!!! I modified the code to work with wookmark (a masonry like jquery plugin) and with just a few changes it works great.
Hi, thanks for the tutorial!
Any chance you could expand on how to add BBQ Hash History so the back button works between filters?
I’ve never done it, but according to the documentation, you would only need to modify things a little bit. The instructions are here: http://isotope.metafizzy.co/v1/docs/hash-history-jquery-bbq.html
Hi Alicia, thank you so much for this tutorial.
All works but I have a doubt about the step number 5.
I don’t understand the row 21: you set the variable optionSet then you don’t use it.
Why do you do this? (I’m a newbie of jQuery).
Sorry, there was an error in the code. It should be
#filters
, instead of.option-set
.Thanks for letting me know.
hello,
i am working with the Shortcodes Ultimate Plugin, where do i integrate the custom loop in my template.php?
For example my loop
I’ve never used that plugin, so I’m not sure how using the plugin affects the coding.
In my example, I used a custom loop so that it can be anywhere in a template (except inside another loop, of course), without affecting other loops on it, and so you can customize it. You can integrate Isotope with a regular loop, though.
Really helpful guide! Thanks
Hi Alicia, thank you for this wonderful tutorial!
Hola Alicia, muchas gracias por tu código y tu tutorial.
Despues de mucho buscar, ya lo tengo funcionando.
Te invitaría a una cerveza!!!
Muchas gracias de nuevo
Hi,
big thanks for the great tutorial!
I’ve almost managed to get it working, it looks like I got an issue with filtering (the filtering class are present and the good ones / http://maquette.denisflorkin.be/__testfx/ but sth. is wrong 🙁 )
Did I miss sth ?
Any help, tips on where to look would be hugely appréciated 🙂
Notice in line 8 of step 2 of the tutorial, where you are generating the list of filters, there is a . (period) as part of the value. In other words, the generated HTML would look like so:
<li><a href='#' data-filter='.65' rel="nofollow">Bandes-annonces</a></li>
With your help it’s now working!
Thank you a lot 😀
Hi and thank you for this tutorial.
I have followed the steps, but I can get it to work. I get the list of categories and posts, but nothing happends when I click the categories?
Without looking at your setup it’s hard to tell, but perhaps the scripts aren’t loading (make sure the paths on step 7 point to where you placed the scripts in your theme).
Hi and thanks for the reply.
I managed to get it working perfectly, it was the paths. I have another problem however. My blog has many posts and I display 20 on each page (1,2,3,4 etc). However, the same 20 posts (latests) are shown on all pages. Any fixes? Thanks agaian
You would need to add pagination parameters. The example in the documentation looks like this:
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );
Thanks, I will try to add that!
Hi,
I have tried this without any luck, I am a bit unsure where to add this code, is it in the loop? My mother theme was paged in the first place, but after editing the loop to your Isotope code, it does not work anymore. Thanks
I manged to resolve this issue. Thanks.
However, I noticed another issue. On a category page, or a tag page, all posts are shown, I assume this is because all items are assigned with the “item” tag. Do you know how to deal with such? 🙂
The tutorial is about showing all posts. It uses a custom loop that brings in all posts. If you want to use it in a category or tag page, and you’d want to see only posts for that category or tag, then use a simple loop. I’d recommend you read more about how to customize loops: http://codex.wordpress.org/The_Loop and http://codex.wordpress.org/Class_Reference/WP_Query
Awesome. Thank you for this. It was very helpful!
Hey, great tut! Do you or anyone here have a demo of your final result? Super anxious to see what it actually looks like. Thanks in advance!
I used Isotope for a project at work, except this one sorts users, instead of posts. It should give you an idea of how the effect would look like.
Hi Alicia,
I’ve got a question. I love the way you explained everything, its very clear. But Everything is displayed on my site including the categories, but when I click on a category nothing happens. The link is #. Did I miss something? Thanks!
It’s hard to tell without looking at your code, but a common mistake is missing the a period (.) in the
data-filter
. Make sure the links look something like this:<li><a href='#' data-filter='.something' rel="nofollow">Something</a></li>
BTW I’m working on localhost
where should we copy step codes ?(index or create isotop php ?)
I use a custom loop, so you can place in any template.
tnx
could you look at my gist
https://gist.github.com/sbbnm/e4b2c3b8926b405ed4af
I use ur method to work isotope with my hueman child theme , but filters and isotope items …are in one column …(dont show grid ) .
I use images loaded to solve problem ..but the result was not affected..
hi. thanks for this best tuturial,,
how can i use isotop with infinit scroll for wordpress?
Sorry, I’ve never used infinite scroll. You’d have to check how to use Isotope with Ajax, I suppose.
Thank you! Great Tutorial 🙂
Hola Alicia, great tutorial !!!
What should I do in order to use isotope for arranging items with different heights (thumbnails/featured images in CPT archive template) and not for filtering ? Thanks
If you don’t want to filter, skip step one. If you are using it in an archive, you probably don’t need a custom loop (step 2), simply use a regular loop. In my example, in step 3, I used the masonry layout mode, which should accommodate items of different heights, and widths. You can learn about additional layout modes here: http://isotope.metafizzy.co/layout-modes.html
Thanks a lot Alicia ! It’s works ! I just have a short question, is it possible to force the filters to act only on the primary page ? When I’m in another page I can’t go back to the filtered content.
I went to your site, and I see the problem. You would have to have two sets of navigation. One for the home page, and another for the other pages. Also, take a look at this tutorial. I haven’t tried it, though.
Hello, Alicia Ramirez I tried to follow this tutorial, but I can´t load categories filter with jQuery Cookie plugin can you help me find the solution, for this links really work in http://www.telmoespanha.pt/ ?
I will appreciate, best regards, Telmo Espanha.
Sorry, Telmo, but I’m not familiar with that plugin. You may want to ask your question at Stack Overload.
Good Evening,
i’d like how to sort instead of to filter posts. Thank you.
On Step 5, you’d have to put in your own code for Isotope. Look at the sorting documentation: http://isotope.metafizzy.co/sorting.html
Thanks Alicia, this a great tutorial!!
Is there a way to have it work with categories and tags. At the moment it works with either, but not both even when I use this:
$termsArray = get_the_terms( $post->ID, "project_category" , "tag");
It seems to sort but when the tag filters are clicked the posts are not showing. If I switch and have tags first like this: $termsArray = get_the_terms( $post->ID, “tag”, “project_category”); then the tags work and categories disappear when the category filter buttons are clicked.
Thanks for your help.
Try this:
$catAndTag = array('project_category', 'tag');
$termsArray = get_the_terms($post->ID, $catAndTag);
That worked! Brilliant, Thanks Alicia 🙂
THANK YOU! Your instructions saved me so much of time!
THANK YOU! You saved my day! 😉
hi,
i created my custom taxonomy : “style”, but when i replace “category” by “style” there’s nothing…could i have help please ?
Does it list your styles? If it does, make sure to also change “category” for “style” on line 5 on step 3. If you have “style” in both places, then it may be a typo, or that no posts have a style applied to them… Without looking at your code or setup, it’s hard to tell. Try posting your code on
Hello
Is it possibleto display 10 posts per page and using pagination with isotope ?
I try to get both pagination and isotope filtering but when i click on page 2, I stille get 10 first posts.
Cheers.
This may not be an issue with Isotope, but of how pagination is being implemented. Make sure to change the loop on step 3 from
$the_query = new WP_Query( 'posts_per_page=50' );
to$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$the_query = new WP_Query('posts_per_page=10&paged=' . $paged ) );
Thank you Alicia!
One more thing, I struggle to get link (cursor pointer) of “everything” when the first category is selected.
Are you experiencing the same?
Cheers.
No, in mine it’s a link, like the others. Make sure the generated code is correct (view the page source, or inspect the link).
Thanks!!!
Hi Alicia, I implemented it in my theme and it like charm now i want to add it through shortcode. can you help me with that. i tried everything is working but filters are not working even data-filter and portfolio list have same class. Here is my code:
Thankx.
You may want to post your question in Stack Overflow. What you are trying to do goes beyond this tutorial.
Unfortunately comments not accepting coding 🙁
Great Alicia,
Your code comments helped me to modify the code by using Types and Views on WP. One issue though: when the page is initialized and all results are given, they are stacked.
When a category is pressed, they form a grid. So I guess it has something to do with the initialisation of the page? Any clue?
Thanks for the understandable explanation.
ottie
I managed to solve it by adding the “imagesLoaded” script (http://imagesloaded.desandro.com/)
In the appendix on the isotope site, it says “imagesLoaded no longer included, but is still recommended.” It did the trick.
Just to let you know 😉
Thanks
In case anyone else is looking for this, you can find it in the Isotope FAQ about overlapping elements.
I’d like to be able to show the category description somewhere on the page after a sort is made. Do you know of a way to do that?
You’d have to use JavaScript, perhaps something like this.
Thank you so much for sharing this!
Hi, first thanks so much for this tutorial and example. I’ve setup the posts filtering in an archive page with foundation block grid and it work great (some styling has to be done). Now i’ve got a question :
I’ve got a “category” widget on my single page sidebar and when i click on a given category in this widget, i want the archive page open with the posts allready filtered. Do you think it can be done ?
Thanks a lot for your advice.
You should look at this: http://isotope.metafizzy.co/filtering.html#url-hash
Is there a way o you can choose which categories show up in the filters? For example enter slug-ids rather than all categories? desperate and i cant find a fix
Just change line 4 on step 2 to modify which terms to get. The documentation is here: https://codex.wordpress.org/Function_Reference/get_terms
I’ve tried that but where would i specify which categories to include?
With the ‘include’ parameter. But if you know the categories you want, then just hard code them in. Write them as HTML, instead of using PHP. You can also ask in StackOverflow.