MixItUp est un plugin jQuery dans la lignée de Masonry ou Isotope (Isotope qui utilise d’ailleurs Masonry) qui permettent d’ordonner et filtrer une partie de votre contenu selon des critères entièrement personnalisables. Créez des filtres personnalisés facilement selon le besoin de votre projet.

Ses plus

Pour ne pas avoir tellement exploré ses grandes soeurs, je vais avoir du mal à bien comparer les extensions, alors je vais surtout vous présenter ce qui m’a plu sur ce plugin jQuery.

  • La facilité de mise en place
  • L’API qui permet d’accéder à pas mal de choses
  • Les animations et effet mettant à profit CSS3
  • Le poids du plugin (14ko non gzippé)
  • Possibilité de faire varier la mise en page (plus d’info sur la démo en anglais)
  • Les filtres personnalisables

Ses moins

Il y en a toujours, voici ceux que j’ai noté :

  • Il ne propose pas de mise en page « serrée » comme le propose Masonry
  • Le tutoriel de base en anglais invite à faire des choses pas top côté accessibilité/bonnes pratiques
  • Il y a quelques bugs visuels variables en fonction du navigateur (vraiment très légers)
  • Les animations ne fonctionnent pas sur IE < 9… :p

Voyons comment le mettre en place simplement.

Mise en place de MixItUp

Il ne faut pas oublier que JavaScript doit être une sur-couche à un contenu existant sur votre site web. Si vous partez de cette réflexion, alors vous n’aurez jamais de problème si votre visiteur navigue sans JavaScript (volontairement ou non).

Voir la démonstration

Partons donc du principe que vous avez une belle galerie dont le HTML a cette forme :

<ul id="grid">
	<li class="mix trees" data-alphabetic="Arbres" data-numeric="6">
		<img src="img/trees.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix eyes human" data-alphabetic="Yeux d'humain" data-numeric="5">
		<img src="img/human-eye2.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix animals eyes" data-alphabetic="Yeux d'animaux" data-numeric="4">
		<img src="img/tiger-eye.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix trees" data-alphabetic="Arbres" data-numeric="1">
		<img src="img/trees2.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix animals trees" data-alphabetic="Panda Roux" data-numeric="2">
		<img src="img/panda-roux.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix humans tree" data-alphabetic="Silhouette" data-numeric="3">
		<img src="img/silhouette.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix animals" data-alphabetic="Renard" data-numeric="8">
		<img src="img/fox.jpg" width="240" height="160" alt="">
	</li>
	<li class="mix humans eye" data-alphabetic="Humain" data-numeric="7">
		<img src="img/human-eye.jpg" width="240" height="160" alt="">
	</li>
</ul>

Notez bien que la classe « .mix » est associée à tous les items de liste, ensuite chaque item possède des classes complémentaires permettant de regrouper les contenus. (trees, animals, humans, etc.)
Les attributs HTML5 data-alphabetic et data-numeric sont des attributs personnalisés que je donne en guise d’exemple et qui permettront d’ordonner les items suivants des filtres précis.

Nous ajoutons donc l’appel à la bibliothèque jQuery, puis au plugin.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.mixitup.min.js"></script>

J’ai bêtement testé avec la version 2.0 de jQuery, mais ce script est probablement compatible avec d’autres versions.
Ces deux scripts sont à placer au plus proche de la balise de cloture </body>

Ensuite nous allons mettre un peu de JS pour afficher des filtres et quelques commandes pour trier notre galerie. Ajoutez ce code après les deux appels JS précédents :

<script type="text/javascript">
 
$(function(){
	// on ajoute une classe "js" sur body
	$('body').addClass('js');
 
	/* 
		Ici nous placerons les portions
		de code JS qui vont suivre.
	*/
 
});
</script>

Entrez ce code JS (à l’emplacement du commentaire précédent) afin d’insérer les filtres de notre galerie :

$('h2:first').before('<div class="filters">'+
	'<div class="col">'+
		'<h2>Filtres</h2>'
		+
		'<ul>'+
			'<li><button type="button" class="filter" data-filter="trees">Arbres</button></li>'+
			'<li><button type="button" class="filter" data-filter="eyes">Yeux</button></li>'+
			'<li><button type="button" class="filter" data-filter="animals">Animaux</button></li>'+
			'<li><button type="button" class="filter" data-filter="humans">Humain</button></li>'+
			'<li><button type="button" class="filter all"  data-filter="mix">Toutes</button></li>'+
		'</ul>'+
	'</div>'
	+
	'<div class="col">'+
		'<h2>Ordonner par</h2>'+
		'<ul>'+
			'<li><button type="button" class="sort" data-sort="data-alphabetic" data-order="desc">Lettre Desc.</button></li>'+
			'<li><button type="button" class="sort" data-sort="data-alphabetic" data-order="asc">Lettre Asc.</button></li>'+
			'<li><button type="button" class="sort line" data-sort="data-numeric" data-order="desc">Numérique Desc.</button></li>'+
			'<li><button type="button" class="sort" data-sort="data-numeric" data-order="asc">Numérique Asc.</button></li>'+
			'<li><button type="button" class="sort line active" data-sort="default" data-order="asc">Normal</button></li>'+
			// apparition dans le DOM, desc = inverse du DOM 
			'<li><button type="button" class="sort" data-sort="random">Aléatoire</button></li>'+
		'</ul>'+
	'</div>'+
'</div>');

Nous utilisons la concaténation (symbole « + ») dans le code JS pour conserver une certaine indentation qui permet de faciliter la lecture du code.

Notez sur le premier gros bloc, que ces filtres sont associés aux classes de nos items de galerie. L’attribut personnalisé data-filter prend comme information l’un des groupes mentionné précédemment comme une classe d’items de galerie (trees, animals, etc.)
Le deuxième gros bloc regroupe les filtres alphabétiques et numériques, et prennent comme valeur le nom de l’attribut personnalisé des items de galerie. (un peu complexe comme cheminement, je vous l’accorde).

Enfin, pour initialiser le plugin, il faut ajouter à la suite de notre JS, ce petit bout de code :

$('#grid').mixitup({
	effects: ['fade','scale','rotateZ'],
});

Ici avec les options utilisées sur la démo de l’article.

Il nous faut insérer un peu de CSS pour que les animations fonctionnent bien, CSS que nous n’appliquerons que si JS est activé.
Cela tombe bien puisque nous ajoutons une classe « js » lorsque notre code JS précédent est fonctionnel.

.js #grid li {
	display: none;
	opacity: 0;
}

Placez ce code dans votre feuille de styles principale si vous le souhaitez :)

Pour ceux qui le souhaitent, voici quelques styles pour les boutons de filtre, mais à vous d’adapter bien entendu.

.filters li {
	display: inline;
}
.filters button {
	display: inline-block;
	margin: 3px 3px 0 0;
	padding: 3px 10px;
	border: 1px solid #ddd;
	background: #eee;
	cursor: pointer;
}
.filters button:focus {
	border: 1px dashed #1591E0;
	outline: 0 none;
}
.filters button.all {
	background: #ddd;
}
.filters button.active {
	color: #f2f2f2;
	border-color: #1591e0;
	background: #1591e0;
}

Qu’avons nous produit ?

Avec ce procédé nous avons amélioré l’expérience utilisateur pour une partie des utilisateurs que l’on a tendance à facilement oublier, soit parce qu’on n’en a pas conscience, soit parce qu’on est développeur fainéant ;) :

  • les personnes qui naviguent sans JS n’ont pas d’éléments perturbants (liste de filtres inactifs), ils bénéficient juste d’une simple galerie
  • les personnes qui naviguent au clavier ont le bénéfice du focus sur les boutons d’action
  • le focus est stylé de manière à savoir où nous nous trouvons à la navigation clavier
  • l’élément button peut porter l’attribut title qui pourra offrir une information plus importante sur l’évènement déclenché par le bouton

Bref, votre code est plus accessible et plus cohérent.
C’est cet aspect des choses que le tutoriel officiel du plugin oublie complètement.

Et voilà !
Si vous avez des questions, ça se passe plus bas ;)

Voir la démonstration