Les Sprites CSS

Je pense que vous êtes nombreux a avoir entendu parler des sprites CSS et que même certains d'entrevous les utilises déjà. C'est une technique encore un peu obscure et trop peu utilisée !

Que-est ce que des "Sprites CSS"

Rien de bien sorcier en fait. Il s'agit d'une technique qui consiste à regrouper toutes (ou une partie) de vos images utilisées dans vos CSS en une seule et de la positionner ensuite via des coordonnées X et Y. Les parties de votre site ayant besoin d'afficher une des images agiront en fait comme une fenêtre donnant sur votre sprite !

Voici une illustration :

sprites-css

Le bloc H1 laisse apparaitre une des images se trouvant sur le sprite, les autres n'étant pas visibles puisque "hors bloc". Pour vous, la seule chose qui change c'est qu'au lieu de mettre :

h1{
        background: transparent url(img/titre-h1.png) 0 0 no-repeat;
}

Vous aurez quelque chose du style:

h1{
        background: transparent url(img/sprite.png) 0 -250px no-repeat;
}

Voici un exemple de sprite venant de youtube:

sprites-css-597-150x150

Pourquoi utiliser les sprites CSS ?

Le fait de remplacer une dizaine (ou plus) d'images par une seule va permettre de soulager votre serveur qui ne devrait plus se taper des dizaines de requêtes HTTP à chaque page affichée. Cela se traduit donc par une charge moins élevée (et donc de la puissance disponible pour d'autres taches) et un affichage plus rapide. De plus, si vous utilisez des liens avec des images au survol (:hover), il n'y a plus de temps de latence pour l'utilisateur puisque toutes les images sont chargées d'un coup.

Pour ce qui est du poids, là rien de spécial, en général le sprite fait sensiblement le même poids que l'ensemble des images le composant, même si la superficie est plus importante. De plus, vous pourrez optimiser (voir smush.it) votre sprite en une seule fois, plutôt pratique.

Trop beau pour être vrai ?

Les sprites sont à manipuler avec précautions. Le positionnement de vos images doit être bien réfléchi pour ne pas se retrouver avec des problèmes de conceptions (plusieurs images visibles dans un élément, ....). Un des autres inconvenant c'est que pour faire une simple modification de l'une de vos images, il faut re-générer le sprite en entier.

Et enfin, les sprites ont leurs limites, notamment dans le cas d'images répétées (repeat, repeat-x, repeat-y) ou d'alignement différent (background-position: top right; background-position: bottom left;). Nous verrons ces cas particuliers un peu plus loin.

Je suis convaincu, je veux faire mon 1er sprite CSS !

Selon la complexité de votre design, il va être plus ou moins facile de faire votre sprite. Dans le cas où vos images ne sont pas répétées et s'alignent toutes du même coté (droite ou gauche), la méthode est assez simple puisqu'il suffit "d'empiler" vos images en laissant une marge entre chaque, comme ceci:

sprites-css-5971-50x150

Pensez a laisser le fond transparent (ou blanc si votre design le permet) et d'enregistrer le tout en gif ou png avec transparence.

Ensuite, il faut placer votre sprite de la manière suivante:

/* Affichage de l'icône "forum" de du sprite ci-dessus*/
.forum h1{
        background: transparent url(img/sprite.png) 0 -320px no-repeat;
}

Donc ici on a décalé notre sprite de 320 pixels vers le haut. Cette valeur correspond tout simplement à la distance entre le haut du sprite et le haut de l'icône "Forum". Pour l'icône "Facebook" qui se trouve à 95 pixels du bord, on écrira:

a.facebook{
        background: transparent url(img/sprite.png) 0 -95px no-repeat;
}

Cela n'a donc rien de bien sorcier 😉

Et si vous ne voulez pas sortir votre photoshop, il existe des générateurs de sprites permettant de créer une image unique depuis un zip contenant toutes vos images. Personnellement je recommande celui-ci: spritegen
Il est assez complet et en français. Il vous suffit dons d'uploader votre zip contenant vos images et l'application vous retournera le sprite ainsi que les positions CSS à appliquer !

Pensez bien à laisser une marge suffisante pour que 2 images ne soient pas visibles dans vos éléments (ça arrive lorsque vous utilisez un padding trop important par exemple)

Parfait, mais mon design utilise des images alignées de manières différentes

Si vous utilisez des images qui doivent s'aligner à droite et d'autres à gauche ou parfois en bas, la conception de votre sprite va demander une petite adaptation ! Attention, je parle ici d'images de background ayant un conteneur beaucoup plus grand qu'elles, comme la cas d'un titre Hx (largeur souvent importante), du body (hauteur importante), etc ...

Voici un exemple :

sprites-css2
(On ne se moque pas de mes images hein ! -_-)

Donc les images qui doivent s'aligner à gauche sont placées à gauche (en fait, ce n'est pas obligatoire, mais c'est plus simple) et les images alignées à droite sont placées sur le bord droit. Pour les images devant s'aligner sur le bas, là il serait préférable de faire une sprite à part pour les regrouper de façon horizontale.

Tout ce bidouillage à cause du manque d'offset pour les alignements droite et bas. Car autant il est possible de placer une image précisément tout en la "fixant" à gauche ou en haut, autant dès qu'on la fixe à droite ou en bas il est impossible de préciser la valeur en pixels. L'autre chose ennuyante avec les alignements à droite, c'est IE6 ! Oui encore lui ! Il semblerait que le fait d'utiliser une valeur en toutes lettres et une valeur en pixels dans le positionnement créer des bugs d'affichage, par exemple un background-position: right -100px; risque de ne pas donner le résultat escompté.

Les images répétées

Les images utilisant la propriété background-repeat: repeat; ne peuvent pas être incluse dans une sprite, tout simplement parce qu'elles ont besoin d'être répétées à la fois sur la verticale et sur l'horizontale

Pour les autres, il suffit de regrouper les images qui doivent se répéter sur l'axe Y dans une sprite horizontale et les images qui doivent se répéter sur l'axe X dans une sprite verticale.

sprites-css3

Un détails qui a son importance, comme en général vos images de répétition servent à remplir parfaitement une zone de votre design (sans espaces/marges donc), il faut penser à bien remplir toute la surface (en hauteur dans le cas d'un repeat-y et en largeur dans la cas d'un repeat-x). Voici un exemple (va falloir zoomer pour bien vous rendre compte). Donc sur cette sprite, les images prennent toute la hauteur (2 pixels dans ce cas) sans laisser de vide pour pouvoir être répétées verticalement.

Conclusions

Les sprites CSS permettent d'améliorer les performances de votre site de façon significative. Par contre selon la configuration de votre design il pourra être plus ou moins laborieux de construire vos sprites.

-----

Articles relatifs

  • Très bon article,
    Même si à mon sens, ça commence de plus en plus a être au niveau protocole.
    Le HTTP embarque un seul objet.
    Mais bon, notre cher géant Google devrait arranger cela avec le http://dev.chromium.org/spdy Speedy 🙂
    En attendant, cette article est parfait (je me répète ?) et il est vrai que les sprites CSS sont une bonne alternatives au load/unload cache 🙂
    Merci !

  • Chris

    Haha, merci pour cet article qui vient bien à point 🙂 Je bookmarke pour y revenir calmement dés que je m’attèle à ça sur mes blogs. Thanks julien 😉

  • Pingback: blog de Nicolas Feray » Bookmarks for 29th décembre through 4th janvier()

  • LbSquat

    Merci pour cet article Julien, j’ai déjà testé mais tout ça va me servir pour mon prochain thème wp.

  • Julien

    @Julien Breux
    Merci 🙂

    Oui Google semble vouloir dépoussiérer tous ça. Un nouveau protocole plus adapté je ne suis pas contre. Mais à mon avis ça risque de prendre du temps avant d’être completement éprouvé !

  • Julien

    @Chris
    C’est grâce/à cause de toi que j’ai enfin fini cet article commencé il y a quelques semaines 🙂

    @LbSquat
    Héhé 😉

  • Très bon article. Je vais essayer d’utiliser plus souvent cette méthode.

  • Jakikiller
  • Une astuce très intéressante et finalement simple à mettre en oeuvre : il suffisait d’y penser !!! Merci pour cet article intéressant et clair et pour cette astuce à conserver dans un coin.

  • Christophe

    Sympa l’article, je ne connaissais pas du tout le concept du sprite css.
    Une question, un doute subsiste : faut-il que le sprite soit réalisé uniquement en png ou bien ?
    Si oui, le problème se pose alors pour l’ersatz de navigateur qu’est IE6 (près de 20% de part de marché tout de même en 2009) qui ne gère le png/la transparence que par le biais de lourds artifices (scripts javascript, hacks CSS), et au final en voulant gagner en perf, he bien on y perd…

    Je sais il y a toujours un empêcheur de tourner en rond, mais ton avis m’intéresse.
    A te lire.

  • Christophe

    Re moi,

    sympa ton plugin pour les acronymes automatiques.
    C’est quoi son petit nom ?

  • Julien

    @Christophe
    Hello. Alors comme précisé dans l’article, on peut aussi utiliser du gif, celà conserve la transparence même pour ie6 (mais pas de transparence partielle du coup). Et si il n’y a pas besoin de transparence, ça peux même se faire en jpg 😉

    Pour le plugin, il s’agit simplement de « acronyms » .

  • J’utilise depuis pas mal de temps les sprites pour réduire le temps de chargement des pages,
    il existe un outil vraiment très performant pour ça : http://spriteme.org/

  • Christophe

    @Julien
    merci de ta réponse et je ne connaissais pas ce plugin.

  • Perso j’utilise un outil (http://csssprites.org/) pour générer automatiquement les sprites au moment du déploiement (via une tache ant). C’est beaucoup plus simple!

  • sebastien | ARCHIparmentier

    Bah alors, on n’a plus de nouvelles ?

  • Pingback: Exemples sprite CSS | Le Courrier Industriel()

  • Pingback: Dossier Optimiser le temps de chargement : 1. Les images et sprites | Développement Web, Webdesign, SEO, Multimédia - Guillaume Voisin, Ingénieur Web()

  • Pingback: Surprise de la rentrée: un nouveau thème | Emmanuel GEORJON()

  • Pingback: Les sprites CSS | Portfolio - Web Developer - Jonathan Debaere()

  • Pingback: Les Sprites CSS : Utilisation et technique | ikomeo Design()

  • Pingback: [ASP.NET] Performance Tips 3 : Combiner des fichiers Javascript et CSS()

  • Laura

    Bonjour à tous,
    Je recherche une perle rare… un développeur JavaScript maitrisant Sprites CSS. Si vous êtes cette personne ou si vous la connaissez n’hésitez pas à me contacter !

    Merci à tous 🙂

  • bleach

    Vraiment bien les articles de ce blog! c’est peut-être pour ça qu’ils sont aussi rare!

  • ma question est des plus bête : une fois qu’on a généré le sprite et le css on en fait quoi ? ou… on les met où ? merci pour une réponse

  • Sergejack

    Cette méthode est très compromise par les navigateurs modernes qui font du blur (antialisaing) et où on peut rapidement se retrouver avec des tranches se « bavant » les unes sur les autres.

  • elbakai

    Merci bien SVP est ce que vous pouvez mettre des exemples sur les techniques de sprite pour les images qui seront utilisé la propriété repeat

  • si je comprends bien, c’est uniquement pour les Background images? Merci

  • Pingback: Les Sprites CSS | Webdesign Mag()