Content Filter (JavaScript & CSS3 - filter by class)
by
, 09-19-2015 at 11:50 PM (58895 Views)
Let visitors select categories from your portfolio/ film collection/ club page, etc., and view them in a collapsed group, with this simple JS and CSS3 filter.
Where you might use a filtering script
- to filter your portfolio (web design, graphics, print, media production, etc.)
- to filter you film collection by genre (horror, comedy, romance, western, etc.)
- to filter youth clubs by age or gender
- to filter study periods by subject (or free time)
You can create a reasonably usable filter using CSS-only (for modern browsers and IE9+), with a combination of the:not
selector and the checkbox hack, but the 2 methods shown in the link below are difficult to refine without the help of JavaScript.
CSS-Only Content Filter (checkbox hack): http://fofwebdesign.co.uk/template/_testing/filter.htm
The HTML markup for both demos in the CSS-only page begin with an input, and a label, for each filter category. Note that the input id matches the "for" attribute in the label;Then, filter-items are marked-up like this - with a class for each filterable category;Code:<input type="radio" id="blue" class="filter-input" name="filter" /><label for="blue" class="filter-label" onclick>Blue</label>On the CSS side, filtering is achieved with the checkbox hack. Simplified CSS follows...Code:<div class="filter-item blue"></div>
Demo 1 usesopacity:0.1;
, coupled with a CSS transition, to animate a fade on *unselected* filter-items;In English, this line means "When the #blue radio input is checked, fade-out all the filter-items that DO NOT have a .blue class".Code:#blue:checked ~ :not(.blue) { opacity:0.1 }
Demo 2 usesdisplay:none;
to remove *unselected* filter-items from the flow of the document;Almost the same as demo 1, but this line means "When the #blue radio input is checked, hide all the filter-items that DO NOT have a .blue class".Code:#blue:checked ~ :not(.blue) { display:none }
Both demonstrations work well enough, but each has pros and cons.
Demo 1 - PRO: The fade animation looks nice.
Demo 1 - CON: Items remain in the document flow, so it would be difficult to view the results on a long, heavily populated page.
Demo 2 - PRO: Items collapse together and are removed from the document flow, so filtered groups are easy to view.
Demo 2 - CON: No animation, so the visual effect is jarring.
Now, the really annoying thing is that both methods CANNOT be combined because it is not possible to animate display propertiesSo, this is where we turn to JavaScript. And, while we're at it, we can give IE8 support with JS too.
So, I had a long hard think about how I could collapse selected filter-items, AND animate them, and I came up with this possible solution, where the fade animation isn't actually performed on the filter-items at all; I will fade-in a mask over the top of filter-items, and when the mask is at the peak of its opacity (i.e. totally solid) perform thedisplay:none;
switch. When the mask fades away, only the collapsed, filtered items are visible.
FINAL - JavaScript & CSS3 Content Filter: http://fofwebdesign.co.uk/template/_.../filter-js.htm
Looks pretty good! And unlike the CSS-only version, we're not using the checkbox hack, or :not selector, so it's compatible with IE8... albeit without the fade animation... and a half second delay. IE9 suffers these limitations too, but let's not split hairs.
The filter-mask is just another div placed after the filter-items;The CSS for the filter-mask fade-in-out animation looks like this;Code:<div id="filter-mask"></div>Note that the CSS is applied to a "filter-mask" class, while the markup only has a "filter-mask" id. The class will be applied to the div element with JavaScript;Code:.filter-mask { position:absolute; top:0; left:0; bottom:0; right:0; -webkit-animation:filterMask 1s ease-in-out both; animation:filterMask 1s ease-in-out both } @-webkit-keyframes filterMask { 0% { background:transparent } 50% { background:#fff } 100% { background:transparent } } @keyframes filterMask { 0% { background:transparent } 50% { background:#fff } 100% { background:transparent } }When activated - at the click of an input radio - the filterMask() function above applies the "filter-mask" class immediately, then waits for 1 second, and removes it. While the class is applied, the CSS fade-in-out "filterMask" animation takes effect.Code:function filterMask(){ var mask = document.getElementById('filter-mask'); // the div with 'filter-mask' id mask.className = 'filter-mask'; // apply 'filter-mask' class setTimeout(function(){ mask.className = '' }, 1000); // remove 'filter-mask' class after waiting 1 second }
Timing is crucial because midway through the CSS "filterMask" animation, JavaScript will hide *all* the filter-items with this filterHide() function;And then show the *selected* filter-items with this filterShow() function;Code:function filterHide(el){ for (var i = 0; i < el.length; ++i){ el[i].style.display = 'none'; // hide } }Here's a simplified version of the script so you can see how it ties together;Code:function filterShow(el){ for (var i = 0; i < el.length; ++i){ el[i].style.display = 'block'; // show } }
You could setup variables and onclick functions manually for all categories, but it could get a bit messy, so, in the final demo, I have refined the script so that they're generated dynamically from filter categories listed in an array.Code:var filterItems = document.querySelectorAll('.filter-item'); // all filter-items var btnBlue = document.getElementById('blue'); // input radio with 'blue' id var getBlue = document.querySelectorAll('.blue' ); // filter-items with 'blue' class btnBlue.onclick = function(){ // when input radio with 'blue' id is clicked filterMask(); // apply 'filter-mask' class and run 1 second CSS "filterMask" animation setTimeout(function(){ filterHide(filterItems); // hide all filter-items filterShow(getBlue) }, // show filter-items with 'blue' class 500); // wait half a second before filtering selected 'blue' items }
Oh, before I forget, you can apply multiple category classes to filter-items, so that covers you for those items falling in to more than one group.
Get the complete CSS, HTML markup and JavaScript from the source of this page - FINAL - JavaScript & CSS3 Content Filter: http://fofwebdesign.co.uk/template/_.../filter-js.htm
Bye for now. Ask questions below if you need to.