Créez un menu simple avec un sprite CSS

3 octobre 2010

Un sprite CSS consiste à regrouper plusieurs images en une seule et de rendre visible uniquement la partie de l’image qui nous intéresse via la propriété CSS background-position. Cette technique est utilisée afin de réduire le nombre de requêtes HTTP et ainsi d’optimiser la vitesse de chargement des pages web.

Création du sprite

Pour mieux comprendre l’utilité des sprites CSS, nous allons voir comment utiliser cette technique dans un exemple. On souhaite créer un menu composé de quatre rubriques : Opera, WordPress, Firefox et PHP. On voudrait que lorsqu’on survole une rubrique, l’image par défaut soit remplacer par un image qui correspond à l’intitulé.

Exemple pour la rubrique « Opera »

Sans sprite CSS, il faudrait au total cinq images pour illustrer nos quatre rubriques : celle par défaut commune à chaque rubrique, et quatre autres qui s’affichent lors du survol de la souris. On va donc regrouper ces cinq images dans un seul et même fichier. Voici à quoi ça ressemble (voir ci-dessous). Ici, on a choisit le format PNG pour pouvoir jouer sur la couleur de fond avec la partie transparente située sur la partie de gauche de chaque image.

« sprite.png », l’image du sprite CSS

Mise en place du sprite

En ce ce qui concerne le code, rien de bien compliqué. Créez un nouveau dossier pour votre site et créez dedans les fichiers suivants : « index.html » et « style.css ». Ensuite, créez un sous-dossier « images » et placez-y notre fichier « sprite.png » disponible ci-dessus. Puis créez un deuxième sous-dossier « css » et placez-y le fichier style.css. Editez le fichier index.html et mettez-y le code suivant.

index.html

On déclare la feuille de style.

<link rel="stylesheet" type="text/css" href="css/style.css">

On crée une simple liste à puces contenant des rubriques, chacune identifiée par une classe qui va nous permettre d’appliquer le changement d’image au survol de la souris.

<ul class="categorie">
  <li class="opera"><a href="#">Opera</a></li>
  <li class="wordpress"><a href="#">WordPress</a></li>
  <li class="firefox"><a href="#">Firefox</a></li>
  <li class="php"><a href="#">PHP</a></li>
</ul>

Dans le fichier CSS, on commence par annuler l’affichage des puces de la liste. On va ensuite définir le style par défaut lorsque la rubrique n’est pas survolée, c’est-à-dire le style des balises « a », « a:link », et « a:visited ».

style.css

.categorie {
  list-style-type: none;
  font-family: "Helvetica", "Helvetica Neue", "Arial", sans-serif;
  font-weight: bold;
}

.categorie li a, .categorie li a:link, .categorie li a:visited {
  height: 28px;
  width: 217px;
  display: block;
  text-transform: uppercase;
  font-size: 13px;
  line-height: 28px;
  margin-bottom: 5px;
  padding-left: 35px;
  text-align: left;
  background: url(../images/sprite.png) no-repeat;
  color: #05213f;
  background-color: #05213f;
  text-decoration:none;
}

Puis on y ajoute le style de chaque rubrique survolée grâce à la classe appliquée sur la balise « li » et la pseudo-classe « a:hover ». C’est ici qu’intervient le sprite CSS : on met en background notre fichier sprites.png que l’on va déplacer grâce à la propriété background-position. La première valeur définit l’axe des abscisses, la deuxième l’axe des ordonnées. Dans notre exemple, il suffit alors de faire varier la deuxième valeur pour décaler notre image de haut en bas, soit ici des multipes de 28 pixels (hauteur d’une rubrique).

style.css

.categorie li.opera a:hover {
  color: #ca1010;
  background-color: #ca1010;
  background-position: 0px -28px;
}

.categorie li.wordpress a:hover {
  color: #3170a6;
  background-color: #3170a6;
  background-position: 0px -56px;
}

.categorie li.firefox a:hover {
  color: #d2480b;
  background-color: #d2480b;
  background-position: 0px -84px;
}

.categorie li.php a:hover {
  color: #869bdc;
  background-color: #869bdc;
  background-position: 0px -112px;
}

Optimisation de la vitesse de chargement

Maintenant, comparons nos deux versions (sans sprite et avec sprite). Si l’on jette un coup d’œil à Firebug (dans l’onglet Réseau), on a la liste des différentes requêtes HTTP qui se sont exécutées au chargement de la page. Ainsi, on peut comparer la vitesse de chargement du menu qui utilise un sprite et celui qui n’en utilise pas. Vous constaterez que les gains de rapidité ne sont pas négligeables puisqu’on divise le temps de chargement par trois.

963 ms pour le menu sans sprite, 302 ms pour le menu avec sprite

De plus, dans notre exemple, l’usage d’un sprite devient presque indispensable à cause du changement d’image au rollover : en effet, en utilisant une image hover indépendante, le serveur enverrait une requête HTTP pour charger cette image uniquement au passage de la souris, laissant apparaître le background pendant un laps de temps, certes très court (de quelques dixièmes de secondes), mais perceptible à l’œil nu.

Pour résumer, l’utilisation des sprites CSS est donc très pratique pour améliorer les performances de votre site. C’est pourquoi de nombreux sites à fort traffic l’utilisent : Google, Facebook ou encore YouTube.

Requis : aucun
Démonstration : https://www.megaptery.com/wp-content/demos/sprite/
Licence : libre

Commentaires

  • Anonyme

    Bonjour, merci pour cette jolie démonstration des sprites (vive les sprites, woohoo !).

    Je proposerais bien quelques petites améliorations, en revanche.
    Nul besoin de répéter « background: url(../images/sprite.png) no-repeat; » à chaque fois, on peut l’écrire comme attributs de .categorie li a et .categorie li a:hover, et ensuite ne jouer qu’avec le background-position.
    Ensuite, je n’ai pas bien compris l’intérêt du .png, si c’est juste pour laisser la petite partie à gauche visible, pourquoi ne pas avoir rempli cette zone avec de la couleur directement et fait un .jpg ? Si l’image avait été en png translucide, prenant donc la couleur du fond en ‘transparence’, j’aurais compris, mais là l’image est opaque sauf sur ce petit bandeau.

    Ceci dit, vraiment chouette tuto, simple et concis, avec un exemple pertinent =)

    • Anonyme

      Améliorations apportées !

  • Améliorations apportées !