Comment créer des sprites CSS avec ImageMagick?

Les Sprites CSS sont un moyen de réduire le nombre de requêtes HTTP faites sur les ressources images de votre site.

La technique consiste à exploiter un fichier unique pour stocker de multiples images, positionnées les unes à côté des autres. Celles-ci seront ensuite appelées dans la feuille de style grâce à la propriété background-position.

Mais alors comment créer cette image unique sans trop se casser la tête? ImageMagick y répond!

ImageMagick est un logiciel libre, comprenant une bibliothèque, ainsi qu'un ensemble d'utilitaires en ligne de commande, permettant de créer, de convertir, de modifier et d'afficher des images dans un très grand nombre de formats.

Dans mon exemple je vais fusionner toutes les images .png d'un dossier:

convert *.png -append sprite.png

pour les fusionner dans une même ligne verticale; ou bien:

convert *.png +append sprite.png

pour les fusionner dans une même ligne horizontale.. C'est aussi simple que ça!

On peut créer une image plus au moins rectangulaire en combinant les deux dernières commandes et en dessinant colonne par colonne notre sprite (ou ligne par ligne c'est à vous de voir):

convert 1.png 2.png -append col1.png
convert 3.png 4.png -append col2.png
convert col1.png col2.png +append sprite.png

Exemple de résultat: mon fichier sprite d'émoticones sm.png:

Emoticones

J'avais 25 fichiers de 18x18px d'une taille totale de ≈23Ko avec 25 commandes HTTP GET pour pouvoir toutes les afficher et je me retrouve avec un fichier unique d'une taille de ≈17Ko avec une seule commande GET pour afficher toutes les images.

Maintenant que j'ai mon image sprite passons au côté CSS!

Pour afficher une image nous allons créer un récipient et définir son image d'arrière plan et sa position relative dans l'image. Un peu confus non?! Deux exemples pour mieux comprendre..

Disons qu'on veut afficher le Big Grin qui est la première image en haut à gauche de notre sprite; nous allons créer une class sm-biggrin:

.sm-biggrin {
 background: url('sm.png');
 display: inline-block;
 width: 18px;
 height: 18px;
 background-position: 0px 0px;
}

Et l'appliquer à un élément:

<i class="sm-biggrin"></i>

et voilà le résultat:

Disons maintenant qu'on veut l'émoticone du gars qui dort; c'est la 4ème depuis la gauche sur la 2ème ligne; en CSS ça donne:

.sm-sleep {
 background: url('sm.png') no-repeat;
 display: inline-block;
 width: 18px;
 height: 18px;
 background-position: -54px -18px;
}

Pour le HTML:

<i class="sm-sleep"></i>

Et voilà le travail: C'est aussi simple que ça!

Quelques explications tout-de-même...

Par background: url('sm.png') nous avons défini l'image sur laquelle on va se baser pour l'arrière plan; no-repeat c'est-à-dire que l'image ne sera pas répétée pour combler l'excès s'il existe.

Pour display: inline-block, avec cette valeur de la propriété display, vous allez avoir des éléments qui vont se comporter à la fois comme s'ils étaient de type block et de type inline. Concrètement, ça va donner les caractéristiques suivantes:

  • Les éléments de type inline-block peuvent contenir à la fois d'autres éléments de type block, des éléments de type inline ou du texte.
  • Il est possible de fixer une largeur et une hauteur à ces éléments
  • Par défaut, leurs largeurs et leurs hauteurs dépendent du contenu de l'élément
  • Ils s'écoulent selon le flux du texte HTML
Ca tombe bien c'est ce dont on a besoin justement! Ah! Je viens d'utiliser une émoticone.. Une autre?! Bon passons..

Pour width et height c'est respectivement la largeur et la hauteur de la zone d'image qu'on va utilser.

Pour background-position c'est la position sur l'image de la zone d'image qu'on va utiliser; les valeurs s'expriment en négatif comme vous pouvez constater. -54px à partir de la gauche et -18px à partir du haut pour notre émoticone du gars qui dort.

Nous pouvons créer deux classes: l'une commune pour background, display, width et height - puisqu'ils se répètent pour toutes les émoticones - et l'autre individuelle pour background-position:

.sm {
 background: url('sm.png') no-repeat;
 display: inline-block;
 width: 18px;
 height: 18px;
}
.sm-sleep {
 background-position: -54px -18px;
}

et notre émoticone sera donc:

<i class="sm sm-sleep"></i>

Résultat:

Voilà c'est aussi simple que ça!

Des questions? Des remarques? N'hésitez surtout pas!


Lire aussi: