JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://imagesloaded.desandro.com/imagesloaded.pkgd.min.js"></script>
<script src="http://isotope.metafizzy.co/isotope.pkgd.min.js"></script>
<hr class="bigDivide">
<div id="headerContainer">
<div class="header">november 2014
</div>
</div>
<hr class="bigDivide">
<!--FILTERING-->
<div id="filterContainer">
<div id="filters">
<div class="ui-group">
<span class="header2">filter by</span><br>
<div class="button-group" data-filter-group="filter1">
<button class="button is-checked" data-filter="*">turn off filter</button>
<button class="button" data-filter=".chris">chris</button>
<button class="button" data-filter=".morgan">morgan</button>
<button class="button" data-filter=".mason">mason</button>
<button class="button" data-filter=".morganmason">morgan & mason</button>
<button class="button" data-filter=".grandparents">grandparents</button>
<button class="button" data-filter=".auntsuncles">aunts & uncles</button>
</div>
</div>
<div class="ui-group">
<span class="header2">optional filters</span><br>
<div class="button-group " data-filter-group="filter2">
<button class="button is-checked" data-filter="*">turn off filter</button>
<button class="button" data-filter=".sport">sports</button>
<button class="button" data-filter=".school">school</button>
<button class="button" data-filter=".2014">2014</button>
<button class="button" data-filter=".sep">september</button>
<button class="button" data-filter=".nov">november</button>
</div>
</div>
</div>
</div>
<!--SORTING-->
<div id="sortContainer">
<span class="header2">sort by...</span><br>
<div id="sorts" class="button-group">
<button class="button is-checked" data-sort-by="original-order">turn off sort</button>
<button class="button" data-sort-by="name">first name</button>
<button class="button" data-sort-by="sport">sport</button>
<button class="button"...
CSS
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {margin-left:auto; margin-right:auto; padding:0px; background:url('http://subtlepatterns.com/patterns/tweed.png'); font-family: 'Open Sans', sans-serif; letter-spacing:1px;}
html {overflow-y: scroll;}
/* - HEADER --- */
#headerContainer {width:80%; margin-left:auto; margin-right:auto; overflow:hidden; text-align:center;}
.header {font-size:24px; color:#fff; font-weight:300; margin: 0 0 0 0;}
.header2 {font-size:18px; color:#999; font-weight:300; margin: 0 0 0 0;}
/* - FILTER --- */
#filterContainer {width:80%; margin-top:20px; margin-left:auto; margin-right:auto; text-align:left;}
#filters {}
#filter1 {}
#filter2 {}
/* - UI GROUP --- */
.ui-group {display: inline-block; margin-top:20px; margin-right:0px;}
/* - BUTTON-GROUP --- */
.button-group {display:inline-block; margin-right:0px; margin-top:5px}
.button-group:after {content: ''; display:block; clear:both;}
.button-group .button {float:left; border-radius:0; margin-left:0; margin-right:1px; margin-bottom:1px;}
.button-group .button:first-child {/*border-radius:8px 0 0 8px;*/}
.button-group .button:last-child {/*border-radius:0 8px 8px 0;*/}
/* - BUTTON --- */
.button {display:inline-block; padding:8px 14px 8px 14px; background:#eee; border:none; border-radius:7px; background-image:linear-gradient( to bottom, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.2) );color:#222; font-size:14px; text-align:center; /*text-shadow:0 1px white;*/ cursor:pointer;}
.button:hover {background-color:#C6DAC9;/*text-shadow:0 1px hsla(0, 0%, 100%, 0.5);*/ color:#222;}
.button:active, .button.is-checked {background-color:#8FB794;}
.button.is-checked {color:white; /*text-shadow:0 -1px hsla(0, 0%, 0%, 0.8);*/}
.button:active {box-shadow:inset 0px 2px 8px hsla(128,22%,46%,1);}
/* - SORT --- */
#sortContainer {width:80%; margin-left:auto; margin-right:auto; margin-top:20px; text-align:left;}
#sorts {}
#sort1 {}
/* - SHUFFLE...
JavaScript
$( function() {
var $container = $('.isotope').imagesLoaded( function() {
$container.isotope({
//options
sortBy : 'original-order',
itemSelector: '.galleryItem',
resizable: false, //disable normal resizing
layoutMode:'fitRows',
filter: function() {
var isMatched = true;
var $this = $(this);
for ( var prop in filters ) {
var filter = filters[ prop ];
// use function if it matches
filter = filterFns[ filter ] || filter;
// test each filter
if ( filter ) {
isMatched = isMatched && $(this).is( filter );
}
// break if not matched
if ( !isMatched ) {
break;
}
}
return isMatched;
},
getSortData: {
name: '.name',
sport: '.sport',
day: function( itemElem ) {
var day = $( itemElem ).find('.day').text();
return parseFloat( day.replace( /[\(\)]/g, '') );
},
month: function( itemElem ) {
var month = $( itemElem ).find('.month').text();
return parseFloat( month.replace( /[\(\)]/g, '') );
},
year: function( itemElem ) {
var year = $( itemElem ).find('.year').text();
return parseFloat( year.replace( /[\(\)]/g, '') );
},
activity: '.activity'
}
});
// store filter for each group
var filters = {};
$('#filters').on( 'click', '.button', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.button-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
filters[ filterGroup ] = $this.attr('data-filter');
// arrange, and use filter fn
$container.isotope('arrange');
});
// filter functions
var filterFns = {};
// bind filter1 button click
$('#filter1').on( 'click', 'button', function() {
var filterValue = $( this ).attr('data-filter');
// use filterFn if matches value
filterValue = filterFns[ filterValue ] ||...