On utilise souvent Javascript pour précharger les images d'une page web ou bien gérer l'apparence de survol, ou d'état, de certains éléments. Cependant, bien que cette approche soit très éfficace et qu'elle ait longuement été documenté, elle présente quelques ennuis. Parmis les principaux on peut citer le fait que les designers ont besoins de représenter une interface au travers d'un grand nombre de fichiers et de ce fait cela nécessite un grand nombre de requêtes client serveur. Nous allons voir qu'il existe une autre approche.
Depuis longtemps déjà, il est possible de coupler la souplesse de CSS a une ancienne technique utilisée lors du développement de logiciel. Cette technique consiste à regrouper l'ensemble de l'iconographie d'une interface, et de ses états, sur une même et unique planche graphique. Il suffit alors d'indiquer la position d'un élément sur cette planche pour l'utiliser. Ceci permet deux choses. D'une part, de regrouper l'ensemble des éléments visuel sur un même document commun, et donc d'en simplifier la mise à jour. Et, d'autre part, de ne réaliser qu'un seul chargement de fichiers du fait qu'il n'y a qu'un seul document, ce qui a pour effet de réduire grandement les échanges avec le serveur, et de supprimer les latences liées au préchargement. Cette technique se base sur l'utilisation de Sprites, nous allons au cours de cette étape en décortiquer les principales mises en oeuvre.
Présentation et définition
Commencons par une bonne vieille définition de la technique des Sprites. Les sprites sont apparus pour des besoins de composition d'interfaces graphiques lors de la réalisation d'applications puis ils ont été repris, et améliorés, lors de la création de jeu vidéo en 2d. La technique consiste a représenter côte à côte, sur une grille bitmap, un ensemble d'éléments graphiques devant composer, et/ou compléter, le visuel d'une interface. Il suffit alors par un jeu de code approprié de venir localiser dans cette grille la position de l'élément souhaité et de l'afficher sur l'interface, en prenant soin toutefois de masquer le reste de la grille. Ceci à l'avantage de centraliser l'ensemble des éléments graphiques en un seul fichier et d'en accélerer les performances d'utilisation.
Coupler cette technique avec l'utilisation des CSS est un vrai jeu d'enfant, c'est un peu comme si nous jouions à la battaille navale. Il suffit simplement de paramétrer correctement la propriété background-image, en gérant la position background-position et les dimensions de l'élément receveur width, height ... et ce... au pixel près. Nous allons explorer quelques unes de ces possibilités au cours de cet article afin de mieux en comprendre les mécaniques. Nous commencerons par la mise en place d'un menu visuel puis nous irons un peu plus loin en décortiquant une carte image.
Préparation du contexte
Mise en place de la structure du menu
Afin d'illustrer la mise en pratique et l'utilisation des Sprites, prenons l'exemple simple d'un bandeau interactif. Un simple menu. Imaginons donc un menu intégralement visuel, portant sur des bouquets de fleurs, qui propose un ensemble d'élément présentant chacun un choix de composition florale différent. Avant de commencer, vous pouvez télécharger l'ensemble des fichiers nécessaires. Comme pour toute utilisation de CSS, il faut au préalable définir la structure HTML. Une structure de liste non ordonnée sera très bien adaptée pour ce genre de contexte :
<ul class="bouquet"> <li>Composé</li> <li>Rose</li> <li>Orange</li> <li>Rouge</li> </ul>
Proposition du visuel
Maintenant du coté visuel, il est facile d'imaginer la représentation de ce menu sous forme de bandeau en ligne. Certes jusque là rien de bien nouveau, ni de bien complexe à mettre en place. En usant de quelques déclarations CSS et images d'arrières plan distinctes, le tour serait vite joué. Poussons alors l'interactivité en se disant que par défaut ces images pourraient être en niveaux de gris et que seulement au moment du survol l'élèment survollé basculerait alors en mode couleur. Là encore, comme nous l'avons souligné précédemment, bien des techniques permettent ce genre de possibilité. Alors, concentrons nous cette fois ci sur l'emploi de sprites CSS.
Préparation de la feuille CSS de base
Lors de l'emploi de la technique des sprites CSS, il est préférable d'utiliser une feuille CSS de réinitialisation qui veillera à ce que toute marge, ou autre gestion d'affichage par défaut des navigateurs, soit bien controlée et ne viennent pas interferer sur le bon fonctionnement des sprites. Dans le cadre de cet article, nous nous assurerons simplement de la réinitialisation des marges et des bordures. Nous prendrons soin d'inclure ces déclarations directement dans les règles appropriées. Dans un premier temps, délimitons simplement les blocs d'éléments de liste en blocks horizontaux de 100 pixels par 100 pixels. Puis, et uniquement afin de visualiser les block d'éléments de liste, prenons soin d'ajouter une bordure temporaire pour les éléments <li> afin de s'assurer que ceux ci sont bien positionnés.
html, body, a, img, ol, ul, li {
margin: 0;
padding: 0;
border: 0;
}
ul, ol {
list-style:none;
}
.bouquet li{
float:left;
width:100px;
height:100px;
border:dotted 1px red;
}
Gestion du menu en utilisant des psrites CSS
Préparation des sprites
Revenons un instant sur le visuel de base et modifions alors le fichier d'origine pour le préparer suivant la technique d'utilisation de sprites CSS. Ajoutons les éléments en niveaux de gris. Utilisons le même et unique fichier qui maintenant représente dans sa partie haute les éléments bouquets de fleurs en niveaux de gris (images au repos) et dans la partie basse les éléments bouquets de fleurs en couleurs (images survolées). Pour cet exemple l'image totale sera composée de deux rangées de quatre éléments de 150 pixels par 150 pixels, ce qui porte un fichier final de 600 pixels par 300 pixels. Il est a noter que tout autre organisation aurait été acceptable. Quelques soit l'organisation retenue, ce type d'information, dimension totale et par élément, est importante pour la suite, car nous devrons l'utiliser afin de positionner correctement chaque sprite.
Adaptation du code HTML et de le feuille de style CSS
Dans le code HTML actuel, rien ne permet de distinguer un élément de liste d'un autre, nous allons donc devoir ajouter un signe distinctif à chacun d'entre eux. Histoire de simplifier l'approche, nous pouvons utiliser une banale classe pour chaque élément <li>, disons ciblons les respectivement, class="a", class="b", class="c" et class="d". De même, dans les CSS mises en place précédemment nous avions bordé les éléments <li>, et nous leur avions donné une dimensions de 100 pixels par 100 pixels. Prenons soin de modifier et adapter ce code afin de supprimer la bordure et augmenter la dimension des éléments <li> à 150 pixels par 150 pixels. Une dernière attention est de supprimer l'affichage du contenu textuel en l'indentant de quelques milliers de pixels, n'oublions que nous souhaitons obtenir un menu uniquement visuel.
.bouquet li{
text-indent:-9999px;
float:left;
width:150px;
height:150px;
}
Notre fichier graphique est composé de deux parties, la partie haute qui représente les éléments au repos et la partie basse qui représente les élements survolés. Le fichier faisant 600 pixels par 300 pixels, il nous suffit d'afficher uniquement la partie haute pour représenter le bandeau de la barre de menu au repos. Une fois encore la structure HTML actuelle et plus particulièrement l'élément <ul> nous permet d'appliquer une règle CSS qui va pouvoir prendre en charge cela. Il suffit de préciser une image d'arrière plan et surtout de dimensionner l'élément.
.bouquet {
width:600px;
height:150px;
background-image: url(menu-sprite-complet.jpg);
background-repeat: no-repeat;
background-position: 0px 0px;
}
Gestion du survol
Nous allons faire abstraction que certains vieux navigateurs ne prennent pas en charge la pseudo classe :hover directement appliquée des éléments autre que des liens. Partons du principe que nous restons focalisé sur la gestion des sprites CSS et que nous testons uniquement dans des navigateurs contemporains (sinon il nous faudrait avoir recours à des balises <a>). Bref, ceci précisé, pour gérer l'action lors du survol, nous pouvons utiliser la même image d'arrière plan que celle du menu, mais cette fois ci en ciblant simplement l'élément survolé en le localisant sur la grille bitmap.
Nous pouvons centraliser la définition et la gestion de l'image d'arrière plan sur une règle générique, puis au cas par cas, en s'appuyant sur les classes ajoutées à l'étape précédente, nous viendrons positionner cet arrière plan au pixel près en fonction des besoins. Attention, nous aurions tendance à positionner les éléments de survol en fonction de leur position de la carte, en clair, le premier à 0 pixel, le second à 150 pixels, le troisième à 300 pixels et ainsi de suite... seulement du fait qu'il s'agit d'un décalage à appliquer, il faut que ces valeurs soient négatives. Donc, le premier élément est bien à 0 pixel, mais le second est à -150 pixels, le troisième à -300 pixels et ainsi de suite. Cette remarque s'applique également sur l'axe vertical. Nous obtenons le code suivant :
.bouquet li:hover{
background-image: url(menu-sprite-complet.jpg);
background-repeat: no-repeat;
}
.bouquet li.a:hover{
background-position: 0px -150px;
}
.bouquet li.b:hover{
background-position: -150px -150px;
}
.bouquet li.c:hover{
background-position: -300px -150px;
}
.bouquet li.d:hover{
background-position: -450px -150px;
}
Utiliser les sprites pour gérer une interface utilisateur
Une fois ce principe assimilé, il est facile de comprendre les avantages et la souplesse d'utilisation d'une telle méthode. A présent, si l'on se rapproche de la composition de la grille utilisée par Google, il est très rapide d'en comprednre les tenants et les aboutissants. En regardant chaque icône qui la compose, on s'aperçoit que l'utilisation d'une telle grille ne se limite pas forcément à un simple menu mais que, bien au contraire, l'intégralité de l'identité visuelle d'un site web peut y être représentée, y compris l'éventuelle représentation de ses diverses déclinaisons. Ceci simplifie grandement la maintenance, la mise à jour et l'évolution de la charte graphique.
Il peut être, cependant, complexe de positionner chaque éléments sur la grille, et de fait également complexe de reporter cette position dans les propriétés de feuilles de styles CSS. Il existe diverses astuces, ou approches, qui permettent de simplifier cette tâche. Par exemple, et au risque d'allourdir un peu le fichier bitmap de la grille, et à la différence de l'exemple de Google, il est possible de positionner chaque élément sur une grille plus importante par exemple tous les 100 pixels, et ce sans essayer d'imbriquer au mieux chacun d'entre eux, ni de gagner de l'espace. Il existe également des solution logicielles utilisable sous forme d'applications autonomes ou de tierces parties de logiciels graphiques. En voici quelques unes :
- CSS Sprites Generator
- Générateur de sprites CSS
- Sprite Me
- Smart Sprites
- Sprite.cow
- CSS Sprites Maker - Fireworks
- Atlas CSS - Photoshop
- 8 CSS Sprites Generator Ressources
Carte image en utilisant les Sprites CSS
Il nous arrive de devoir réaliser des cartes images, qu'il s'agisse de la présentation d'un produit ou d'une équipe ou bien pour présenter une réelle carte géographique. Pour cela nous pouvons avoir recours aux balises HTML qui prennent en compte les cartes images. Seulement voilà, les moteurs de recherche, les lecteurs d'écran et certains types de lecteurs n'ont pas accès à la structure du document. Il s'agit là d'une élément quasi 'multimédia' à part entière et pour lequel il n'est pas possible d'en extraire quelques données sémentique que ce soit.
Une fois encore, les Sprites vont pouvoir nous apporter solution. Certes, le découpage des zones de survol ne sera pas autant précis que ce que nous propose les carte images HTML, de même, les fichiers grille images générés peuvent être plus lourds que ce qu'ils ne le seraient avec une carte image, et pour enfoncer le clou, il est certain que la mise en place elle même peut s'avérer parfois complexe... mais ... bien que tout ces premiers points ne soient pas à l'avantage de l'utilisation des sprites CSS... il faut garder à l'esprit que ceux ci nous proposent une gestion plus sémentique de ce type de présentation, que nous gardons une pleine séparation structure / aperçu et qu'enfin, une fois la mécanique mise en place, autant les moteurs de recherche que les personnes pourvues d'un lecteur d'écran pourront toujours accéder à l'information... et de manière transparente.
Présentation d'une carte régionale
La principale difficulté de mise en place pour une carte géographique vient une fois encore de la gestion du positionnement des divers éléments et de leur repport dans les déclarations CSS. De plus, pour l'exemple de cette carte nous proposons deux niveaux de survol; un premier niveau qui active la zone de la carte survolée et un second qui se produit lorsqu'on survole la ville chef lieu du département. Ceci nous permet de pousser un peu plus loin la gestion interactive des sprites CSS et d'ouvrir certaines portes. Avant d'aller plus loin, vous pouvez télécharger les fichiers nécessaires.
L'astuce s'appuie comme pour chaque usage des sprites CSS, sur le positionnement de l'image d'arrière plan mais également dans le redimenssionnement de la seconde zone lors du survol. La détection s'éffectue sur une zone de 10 pixels par 10 pixels, mais une fois survolée la zone se repositionne en 0,0 et prend les dimensions de sa zone parent. N'oublions que nous sommes en positionnement absolu. Un autre point vient du fait qu'il faut porter une particulière attention à la propriété z-index afin de s'assurer que l'élément le plus pertinent soit toujours au premier plan. Il est vrai que la zone réactive n'est pas très précise, mais pour ce genre d'interaction cela n'est pas du tout gênant, ou du moins cela ne devrait pas l'être.
Il ne devrait pas être utile de détailler lignes à lignes le code produit, toutefois si besoin était, n'hésitez pas à nous le faire savoir. Pour l'instant, nous allons simplement nous attarder sur la gestion plus précise d'un département, puis dans un second temps sur la gestion du point de ville (second survol) :
Détails du code nécessaire pour la gestion d'un département
.carte li.dep05 {
left:139px;
top:0;
width:187px;
height:146px;
z-index:100;
}
.carte li.dep05:hover {
background-position: -139px -330px;
}
Détails du code nécessaire pour la gestion d'un point ville
.carte li ul li{
width:10px;
height:10px;
/* background-color:#FCC; */
}
.carte li.gap {
left:69px;
top:86px;
}
.carte li.gap:hover {
top:0;
left:0;
width:187px;
height:146px;
background-position: -533px -330px;
}
Aller plus loin avec les sprites
Si vous êtes convaincus, et nous le souhaitons, par cette méthodes d'utilisation des CSS, nous vous invitons à en poursuivre l'exploration en vous rendant sur les excellents articles suivants, ou encore en tapant sprite CSS dans un moteur de recherche :
- CSS Sprites: What They Are, Why They’re Cool, and How To Use Them
- CSS Sprites: Image Slicing’s Kiss of Death ou sa traduction sur le site de pompage.net
