Filter all night long

Filterizr is a jQuery plugin that searches, sorts, shuffles and applies stunning filters over responsive galleries using CSS3 transitions.

  • Pluggable look & feel (write your CSS effects in the box on the right and hit Filterize!)
  • Smooth performance — optimized for smooth experience on mobile devices
  • Lightweight — around 10.5kb, jQuery is its only dependency
  • Responsive — with your Media Queries (resize the window!)
  • Platform support:
    • Chrome, Firefox, Safari, Opera
    • Android and iOS browsers
    • Edge, IE(v.10+)
  • Open source
  • MIT licensed (i.e. free for all uses)

Get on NPM: npm install filterizr

CSS3 filters in JSON

Write your CSS in JSON in the textarea below. Hit Filterize and test your effects on the demo gallery!

The gallery has been Filterizd!
Your JSON is not valid.
Both filterOutCss and filterInCss must have the same properties, with varying values for CSS3 transitions to work.

Demo Gallery

sample image
1
Busy Streets
sample image
2
Luminous night
sample image
3
City wonders
sample image
4
In production
sample image
5
Industrial site
sample image
6
Peaceful lake
sample image
7
City lights
sample image
8
Dreamhouse
sample image
9
Restless Machines

Filterizr in Action

Here are some of the people who have put Filterizr to use

Install Filterizr

Include Filterizr in your project: <script src="js/jquery.filterizr.min.js"></script>

Create your gallery

To set up your own gallery, modify your HTML as follows:

  1. Add to your items the class filtr-item
  2. Give your items a data-category attribute. Multiple categories must be delimited by ", ".
  3. To sort your items by custom data, include the data-sort attribute.
<div class="filtr-container">
    <div class="filtr-item" data-category="1" data-sort="value">
       <img src="img/sample.jpg" alt="sample">
    </div>
    <div class="filtr-item" data-category="2, 1" data-sort="value">
       <img src="img/sample.jpg" alt="sample">
    </div>
    <div class="filtr-item" data-category="1, 3" data-sort="value">
       <img src="img/sample.jpg" alt="sample">
    </div>
</div>

Set up your controls

Setting up your filter controls is a matter of seconds:

  1. Create your controls, with the markup of your preference. Style them the way you want with your CSS.
  2. Make sure to include the appropriate data attributes as below. This is what Filterizr looks for. Use the value all for an unfiltered gallery.
<ul>
   <!-- For filtering controls add -->
   <li data-filter="all"> All items </li>
   <li data-filter="1"> Category 1 </li>
   <li data-filter="2"> Category 2 </li>
   <li data-filter="3"> Category 3 </li>
   <!-- For a shuffle control add -->
   <li data-shuffle> Shuffle items </li>
   <!-- For sorting controls add -->
   <li data-sortAsc> Ascending </li>
   <li data-sortDesc> Descending </li>
</ul>
<!-- To choose the value by which you want to sort add -->
<select data-sortOrder>
   <option value="domIndex"> Position </option>
   <option value="sortData"> Custom Data </option>
</select>

Instantiate Filterizr

To instantiate and use Filterizr in your app's script, you can:

  1. Use the jQuery extension method to call the constructor
var filterizd = $('.filtr-container').filterizr({
   //options object
});

Customizing Filterizr

Filterizr's magic lies in filterInCss and filterOutCss. If you override any options:

  1. Pass the options object to any of the constructor methods or...
  2. If you have a Filterizr, call its method setOptions(options).
//Default options
var options = {
   animationDuration: 0.5, //in seconds
   filter: 'all', //Initial filter
   callbacks: {
      onFilteringStart: function() { },
      onFilteringEnd: function() { },
      onShufflingStart: function() { },
      onShufflingEnd: function() { },
      onSortingStart: function() { },
      onSortingEnd: function() { }
   },
   delay: 0, //Transition delay in ms
   delayMode: 'progressive', //'progressive' or 'alternate'
   easing: 'ease-out',
   filterOutCss: { //Filtering out animation
      opacity: 0,
      transform: 'scale(0.5)'
   },
   filterInCss: { //Filtering in animation
      opacity: 0,
      transform: 'scale(1)'
   },
   layout: 'sameSize', //See layouts
   selector: '.filtr-container',
   setupControls: true
}
//You can override any of these options and then call...
var filterizd = $('.filtr-container').filterizr(options);
//If you have already instantiated your Filterizr then call...
filterizd.filterizr('setOptions', options);

Filtering Tutorial

Filterizr offers two distinct options when it comes to the aesthetics of filtering items. All you have to do is use the appropriate preset Filterizr control for each one of the options and Filterizr will handle the rest for you. In the section below you can find examples of both modes, what they look like as well as how to set them up.

Active Filter Mode

Control setup

<ul>
   <li data-filter="all"> All </li>
   <li data-filter="1"> Green </li>
   <li data-filter="2"> Orange </li>
   <li data-filter="3"> Purple </li>
   <li data-filter="4"> Mix </li>
</ul>

Description

For this filtering mode all you need to do is to include the data-filter attribute in your controls as depicted above. Each time you switch between filters by clicking a button, items of the corresponding data-category will be shown. This mode uses the .filterizr('filter', targetFilter) method in the background to switch between categories.

1
2
3
4
5
6
7
8
9
10
11
12

Toggle Filter Mode

Control setup

<ul>
   <li data-multifilter="all"> All </li>
   <li data-multifilter="1"> Green </li>
   <li data-multifilter="2"> Orange </li>
   <li data-multifilter="3"> Purple </li>
</ul>

Description

For this filtering mode you need to include the data-multifilter attribute in your controls. Each time you toggle a button, items of the corresponding data-category will be shown or hidden. When all buttons are switched off an unfiltered gallery is shown. This mode uses the .filterizr('toggleFilter', toggledFilter) method in the background to display or hide categories.

1
2
3
4
5
6
7
8
9
10
11
12

Sorting Tutorial

Filterizr offers both some preset options for sorting and enables you sort your items with your own data, using data-attributes.

1-C-X
2-R-B
3-A-D
4-F-J
5-N-Y
6-M-Q
7-S-I
8-O-P

Basic Sorting

Filterizr has some preset options for sorting. In the Install tutorial, in the preset sorting controls a select input element is used to determine the value by which Filterizr's elements are order. The full built-in options are would be as follows:

<select data-sortOrder>
   <option value="domIndex"> Position in DOM </option>
   <option value="sortData"> data-sort Attribute </option>
   <!-- Next two can be used for layouts of varying widths/heights -->
   <option value="w"> Item Width </option>
   <option value="h"> Item Height </option>
</select>

Then you can either use Filterizr's preset controls to sort your elements by that value, or call the corresponding public method like this:


//Example 1: sort by item width, descending.
fltr.filterizr('sort', 'w', 'desc');
//Example 2: sort by the value of data-sort attribute, ascending.
fltr.filterizr('sort', 'sortData', 'asc');

Advanced Sorting

In case you want to have a variety of values by which to sort your elements, Filterizr allows you to add data-attributes with custom names and values to your items and use them for sorting. For example you could have items looking like this:

<div class="filtr-container">
    <div class="filtr-item" data-category="1" data-author="John Doe" data-year="1998" data-novel="Cool book 1">
       <img src="img/sample.jpg" alt="sample">
    </div>
    <div class="filtr-item" data-category="1" data-author="Jane Doe" data-year="2003" data-novel="Cooler book">
       <img src="img/sample.jpg" alt="sample">
    </div>
    <div class="filtr-item" data-category="1" data-author="Jake Doe" data-year="2008" data-novel="Coolest book">
       <img src="img/sample.jpg" alt="sample">
    </div>
</div>

Then all you have to do is add those private data-attribute names to your select input element:

<select data-sortOrder>
   <option value="domIndex"> Position in DOM </option>
   <!-- Other options and then... -->
   <option value="author"> Author Name </option>
   <option value="year"> Year Published </option>
   <option value="novel"> Book Title </option>
</select>

Once again, your sorting controls will take care of the rest. If you wish to use the public API once again you simply pass the value of the option elements as the attr parameter. Just remember to omit the data- part. For example:

//Example 1: sort by author name, descending.
fltr.filterizr('sort', 'author', 'desc');
//Example 2: sort by book title, ascending.
fltr.filterizr('sort', 'novel', 'asc');

Searching Tutorial

Apart from filtering between categories, since v1.2.1 Filterizr now offers you the ability to apply a dynamic filter while typing in a search term as exhibited on the demo page of this website. Setting up the search control of Filterizr is a matter of seconds. All you have to do is include the corresponding control if you would like this added functionality as follows:

<!-- This is what the search control looks like -->
<input type="text" name="search" placeholder="Search..." data-search>

Done! Once your search control is added, Filterizr will handle the rest of the magic!

Delay Modes Tutorial

If you would like to spice up the effect of your Filterizr by making it less synchronous, you could experiment with adding delays between your gallery's items. Filterizr uses by default delayMode: 'progressive' but the value of delay in the options is set to 0. Thus, there is no delay effect by default.

Progressive delay mode

fltr.filterizr('setOptions', { delay: 50, delayMode: 'progressive' });

This delay mode increases the transition-delay property of your items consecutively by the amount you've set the delay option in Filterizr's options. I would suggest a value between 25-50 ms for an optimal effect.

1
2
3
4
5
6
7
8
9
10
11
12

Alternate delay mode

fltr.filterizr('setOptions', { delay: 350, delayMode: 'alternate' });

This delay mode sets the transition-delay property of every other item to the amount you've set the delay option in Filterizr's options. I would suggest a value between 250-400 ms for an optimal effect if you choose this delay mode.

1
2
3
4
5
6
7
8
9
10
11
12

Layouts Tutorial

Same size layout

fltr.filterizr('setOptions', {layout: 'sameSize'});

This layout should be used with items having the same width and height.

1
2
3
4
5
6
7
8
9
10
11
12

Packed layout

fltr.filterizr('setOptions', {layout: 'packed'});

This layout can be used with items of any size and it will make smart decisions about where to place them. It makes use of Jake Gordon's Bin Packing algorithm to place the items in the container.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Same height layout

fltr.filterizr('setOptions', {layout: 'sameHeight'});

This layout should be used with items having the same height and a varying width.

1
2
3
4
5
6
7
8
9
10
11
12

Same width layout

fltr.filterizr('setOptions', {layout: 'sameWidth'});

This layout should be used with items having the same width and a varying height.

1
2
3
4
5
6
7
8
9
10
11
12

Horizontal layout

fltr.filterizr('setOptions', {layout: 'horizontal'});

This layout can be used to lay out your elements horizontally.

1
2
3
4
5
6
7

Vertical layout

fltr.filterizr('setOptions', {layout: 'vertical'});

This layout can be used to lay out your elements vertically.

1
2
3
4
5
6

Documentation

Objects

  • options

Methods

  • filter
  • filterizr
  • shuffle
  • sort
  • setOptions
  • toggleFilter

Events

  • filteringStart
  • filteringEnd
  • shufflingStart
  • shufflingEnd
  • sortingStart
  • sortingEnd

options

//Default options
options = {
   animationDuration: 0.5,
   callbacks: {
      onFilteringStart: function() { },
      onFilteringEnd: function() { },
      onShufflingStart: function() { },
      onShufflingEnd: function() { },
      onSortingStart: function() { },
      onSortingEnd: function() { }
   },
   delay: 0,
   delayMode: 'progressive',
   easing: 'ease-out',
   filter: 'all',
   filterOutCss: {
      opacity: 0,
      transform: 'scale(0.5)'
   },
   filterInCss: {
      opacity: 0,
      transform: 'scale(1)'
   },
   layout: 'sameSize',
   selector: '.filtr-container',
   setupControls: true
}

The properties of Filterizr's options object are:

  • animationDuration (typeof: Number / Default: 0.5)

    The duration of CSS3 transitions, taking place for your effects.

  • callbacks (typeof: Object)

    Used as the namespace for your callbacks.

    • onFilteringStart (typeof: Function / Default: Empty function)

      Called when you fire the filter method.

    • onFilteringEnd (typeof: Function / Default: Empty function)

      Called when the filtering animation is complete.

  • delay (typeof: Number / Default: 0)

    Measured in milliseconds and used to set the value of the transition-delay property of every item. The value of the transition-delay is incremented progressively by the value of delay for every item to create a more progressive version of your effect.

  • delayMode (typeof: String / Default: 'progressive')

    Determines how delay is applied to the transition between items. The two possible values are progressive and alternate. The value of delayMode makes no difference if delay is 0.

  • easing (typeof: String / Default: 'ease-out')

    The easing algorithm used for CSS3 transitions. Look up the CSS3 transition-timing-function property for possible values.

  • filter (typeof: String or Number / Default: 'all')

    The default value can be used for an unfiltered gallery. To initialize a filtered gallery, set this property to your category of choice before instantiating Filterizr.

  • filterOutCss (typeof: Object / Default: { opacity: 0, transform: 'scale(0,0)' })

    An object with CSS properties, written the same way you would write it for jQuery's .css() function. This the transition that plays when your items are being filtered out.

  • filterInCss (typeof: Object / Default: { opacity: 1, transform: 'scale(1,1)' })

    An object with CSS properties, written the same way you would write it for jQuery's .css() function. This the transition that plays when your items are being filtered in.

  • layout (typeof: String / Default: 'sameSize')

    By default sets the layout for items with same width and height. Other possible values are: 'packed' for a layout of items of varying width and height, 'sameWidth' for a layout of items with the same width but varying height. 'sameHeight' for a layout of items with the same height but varying width. 'horizontal' for a layout of items laid out horizontally. 'vertical' for a layout of items laid out vertically. To see a demo of each and every layout, check the Tutorials section.

  • selector (typeof: String / Default: '.filtr-container')

    The selector of the container used for your gallery.

  • setupControls (typeof: Boolean / Default: true)

    If set to true then Filterizr will try to detect and set up filtering, shuffling and sorting controls. In case you have multiple Filterizrs in your view, you might decide to set this to false and set up your own controls, using the public API, so as to avoid interference the controls of your Filterizrs.

Filterizr is set up to work out of the box. If you wish to override the default options you can either:

  1. Pass an options object to the jQuery constructor:
    var filterizd = $('.filtr-container').filterizr({
       //your options here
    })
  2. Override the options using the setOptions method on your Filterizr object:
    filterizd.filterizr('setOptions', {
       //your options here
    })
Please note that if you wish to override the visual effects of Filterizr, you will have to include the same CSS properties with different values in both filterInCss and filterOutCss for CSS3 transitions to work.

filter

.filterizr('filter', targetFilter)

Filter the container to hide/show and rearrange the elements on screen, while switching between categories.

  • targetFilter (typeof: String or Number)

    The target filter towards which to filter the visible category, should be a numerical value based on the data-category attribute of .filtr-item elements. The value 'all' can be used for an unfiltered gallery.

Each time your filter the items the options.filter property of the options object is updated to the value of the new filter applied. This method also fires the onFilteringStart callback if defined.

filterizr

.filterizr([options])

A jQuery extension method registered on jQuery.fn. It can be used on all DOM elements serving as the gallery's container to initialize Filterizr. It returns the jQuery object to facilitate method-chaining.

  • options (typeof: Object / Default: options)

    This optional parameter can be passed to set the Filterizr's options. For more information on defaults look into the options object documentation.

The .filterizr() method can be used to call all Filterizr methods of the public API. For example:
//Filter items
fltr.filterizr('filter', 'all');
//Sort items
fltr.filterizr('sort', 'domIndex', 'asc');
//Shuffle items
fltr.filterizr('shuffle');
//Override options
fltr.filterizr('setOptions', { /* Options */ });

Shuffle

.filterizr('shuffle')

Use to shuffle the elements in random order and rearrange them on screen.

sort

.filterizr('sort' [,attr] [,sortOrder])

Sort your elements based on a certain attribute in ascending or descending order and rearrange them on screen.

  • attr (typeof: String / Default: 'domIndex')

    The attribute based on which the elements are sorted. If not provided it defaults to value 'domIndex' and the elements are sorted based on their initial position in the DOM. If its value is set to 'sortData', the elements are sorted based on the value of the user-defined data-sort attribute. Other possible values includes 'w' or 'h' if you wish to sort your elements by width or height (used for layouts of items of different size). Moreover, it is possible to sort by any custom data-attribute, see below for more information.

  • sortOrder (typeof: String / Default: 'asc')

    Determines whether the elements will be sorted in ascending or descending order. Possible values are 'asc' and 'desc'.

If you pass no arguments to this method, then it will sort your elements based on domOrder in ascending order. If you pass only the first argument, then your elements will be sorted by the attribute value you provided, in ascending order. If you wish to sort your elements by multiple, custom data-attributes (e.g. data-myFirstAttr and data-mySecondAttr) then:

.filterizr('sort', 'myFirstAttr', 'asc'); //just remember to omit the "data-" part
.filterizr('sort', 'mySecondAttr', 'asc');

setOptions

.filterizr('setOptions', options)

Overrides the default for customized options. Use to change the transition effects of the gallery.

  • options (typeof: Object / Default: see options in the docs)

    An object overriding some or all of Filterizr's properties.

This method can be used to change the visual effects of the gallery on the fly, simply by overriding the filterInCss and filterOutCss of the options object.

toggleFilter

.filterizr('toggleFilter', toggledFilter)

Filters the visible items based on a collection of filters toggled on. If all filters are toggled off then an unfiltered gallery is rendered.

  • toggledFilter (typeof: Number)

    The number of the category whose corresponding filter is to be toggled on/off.

This method filters the item based on a collection of toggled on filters. If all of the filters are toggled off then an unfiltered gallery is rendered. The default controls that come with this method are the controls with a data-multifilter attribute. This method also fires the onFilteringStart callback if defined.

filteringStart

.on('filteringStart', callback)

This event is thrown in the filter method to indicate that filtering has started.

To intercept this event you can either override the onFilteringStart callback in the options object:

fltr.filterizr('setOptions', {
   callbacks: {
      onFilteringStart: function() {
         //your code here
      }
   }
})

Or use jQuery:

filtrizr.on('filteringStart', function() {
   //Your code
})

filteringEnd

.on('filteringEnd', callback)

This event is thrown in the filter method to indicate that filtering has ended.

To intercept this event you can either override the onFilteringStart callback in the options object:

fltr.filterizr('setOptions', {
   callbacks: {
      onFilteringEnd: function() {
         //your code here
      }
   }
})

Or use jQuery:

filtrizr.on('filteringEnd', function() {
   //Your code
})

shufflingStart

.on('shufflingStart', callback)

This event is thrown in the shuffle method to indicate that shuffling has begun.

To intercept this event you can either override the onShufflingStart callback in the options object:

fltr.filterizr('setOptions', {
   callbacks: {
      onShufflingStart: function() {
         //your code here
      }
   }
})

Or use jQuery:

filtrizr.on('shufflingStart', function() {
   //Your code
})

shufflingEnd

.on('shufflingEnd', callback)

This event is thrown to indicate that shuffling has ended.

To intercept this event you can either override the onShufflingEnd callback in the options object:

fltr.filterizr('setOptions', {
   callbacks: {
      onShufflingEnd: function() {
         //your code here
      }
   }
})

Or use jQuery:

filtrizr.on('shufflingEnd', function() {
   //Your code
})

sortingStart

.on('sortingStart', callback)

This event is thrown in the sort method to indicate that sorting has begun.

To intercept this event you can either override the onSortingStart callback in the options object:

fltr.filterizr('setOptions', {
   callbacks: {
      onSortingStart: function() {
         //your code here
      }
   }
})

Or use jQuery:

filtrizr.on('sortingStart', function() {
   //Your code
})

sortingEnd

.on('sortingEnd', callback)

This event is thrown to indicate that sorting has ended.

To intercept this event you can either override the onSortingEnd callback in the options object:

fltr.filterizr('setOptions', {
   callbacks: {
      onSortingEnd: function() {
         //your code here
      }
   }
})

Or use jQuery:

filtrizr.on('sortingEnd', function() {
   //Your code
})

FAQ & Caveats

Contents

FAQ

Why did you create filterizr?

While setting up my portfolio I wanted to divide my works into sections and add a transition effect while browsing between them. I came across numerous gallery plugins such as Isotope, MixItUp and even Shuffle.js. All of them are very feature-rich and battle-tested but they didn't quite suit my needs in terms of their filesize, dependencies and/or licensing. Thus, I decided to set up my own gallery plugin.

What makes filterizr different?

Filterizr is higly customizable, with a pluggable look and feel, feature-rich and comes with preset controls. It's filesize is around 10.5kb and its only dependency is jQuery. It performs well on mobile as it tries to minimize the amount of repaint events. Overall, I'd say it is quick, responsive and lightweight. It is open-source and licensed under MIT. Nonetheless, if you need a well-tested plugin with lots of options and a rich community I would suggest taking a look at the aforementioned solutions.

What if I need support for IE 7-9

Filterizr works with CSS3 transitions and as such works for IE10+. If you need support for a similar effect for IE 7-9 I would suggest taking a look into Shuffle.js.

Can I redistribute, sell or alter Filterizr?

As I said Filterizr is licensed under the MIT license. Essentially, this means that you can tamper with it to your heart's content, use it for any sort of project and even sell your modified version of it.

How can I contribute to Filterizr?

If you would like to help build Filterizr into something better, you can find its GitHub repo right here. If you used Filterizr I would appreciate if you could star the repo on GitHub, as well as let me know about your project through this site's contact form! If you wish I could even feature it here!

Caveats

Margins don't work for me?

Please bare in mind that Filterizr has no notion of margins. If you wish to create whitespace I suggest using a wrapper element and set padding on it, both for your items and your container. The width of your items will have to sum up to 100% per row.

There are gaps at the end of my container

Some Filterizr layouts (e.g. sameSize) expect your items' width to sum up to 100% of the container width, which is why you should use relative sizing. In case you need a fluid layout, please set the layout to packed like this: fltr.filterizr({layout: 'packed'}).

My custom effect's performance is slow

If the performance of your Filterizr's effect is not silky smooth, please make sure to read on compositor-only properties as well as hardware-accelerated CSS and go through your code again.

My images appear without height

If the height of your .filtr-item elements depends on images then you might have trouble, because their loading might be slow the height of your items might be messed up. To solve this issue you can either set the height of your images explicitly or perhaps make use of DeSandro's imagesLoaded script which is only 5kb!

Get in touch

If you happen to use Filterizr in your project, please let me know!