Générer des sprites avec Compass

Compass rend bien des services dans un domaine habituellement long, rébarbatif et — il faut le dire — prise de tête à gérer manuellement : la génération d’images en sprite.
Regrouper ses images en une seule est une bonne pratique lorsque l’on vise à améliorer les performances Web d’un site. Les sprites permettent en effet de réduire le nombre de connexions HTTP ouvertes par le navigateur, ce qui contribue à réduire les temps de latence lors de l’attente des réponses du serveur et, de ce fait, à réduire le temps de chargement de la page web.

Usage basique

Basiquement, un sprite se génère en 2 étapes : on importe toutes les images (au format PNG obligatoirement) d’un répertoire puis on inclut les autant de classes CSS qu’il y a d’images. Dans l’exemple qui suit, on considère le dossier icon.

@import "icon/*.png";
@include all-icon-sprites;

Notez que le nom icon du répertoire des images est repris dans le nom du mixin en charge d’inclure les classes CSS automatiquement générées par Compass. Conformément à la documentation, je parlerai de <map> pour faire référence au nom du répertoire d’images, et de <sprite> pour le nom de l’image cible dépourvue de son extension.

Le répertoire contenant 5 images, nous obtenons le code CSS suivant :

.icon-sprite, .icon-fork, .icon-info, .icon-magnifer, .icon-tag, .icon-x {
  background: url('../img/icon-s8021aff651.png') no-repeat;
}
.icon-fork {
  background-position: 0 -72px;
}
.icon-info {
  background-position: 0 -210px;
}
.icon-magnifer {
  background-position: 0 -24px;
}
.icon-tag {
  background-position: 0 -120px;
}
.icon-x {
  background-position: 0 -165px;
}

Compass a créé une classe de base icon-sprite et regroupé dans sa définition la liste des classes qui permettent de cibler chacune des images. Compass applique des décalages appropriés pour positionner le sprite afin d’afficher l’image souhaitée.
Appliquez simplement la classe associée à une image dans votre HTML pour la voir s’afficher en background. Simple et efficace.

Cependant, puisqu’il est question d’icônes ici, ce serait pratique d’include automatiquement la hauteur pour chacune des images. Pour ce faire, déclarez avant l’importation des images la variable $<map>-sprite-dimensions: true :

$icon-sprite-dimensions: true;
@import "icon/*.png";
@include all-icon-sprites;

Les dimensions sont ainsi bien précisées :

.icon-sprite, .icon-fork, .icon-info, .icon-magnifer, .icon-tag, .icon-x {
  background: url('../img/icon-se625a56f57.png') no-repeat;
}
.icon-fork {
  background-position: 0 -72px;
  height: 24px;
  width: 21px;
}
.icon-info {
  background-position: 0 -210px;
  height: 24px;
  width: 12px;
}
.icon-magnifer {
  background-position: 0 -24px;
  height: 24px;
  width: 24px;
}
.icon-tag {
  background-position: 0 -120px;
  height: 24px;
  width: 24px;
}
.icon-x {
  background-position: 0 -165px;
  height: 21px;
  width: 21px;
}
Super. Maintenant vous aimeriez afficher une variante de l’image lorsque l’élément est survolée. Premier réflexe
ajouter les images dans le répertoire en suffixant leur nom par -hover puis ajouter manuellement pour chaque classe générée la gestion du hover. Perdu.
Le support des pseudo-sélecteurs d’état est automatiquement pris en charge par Compass, tant que la variable $disable-magic-sprite-selectors soit fausse (valeur par défaut). Au lieu de suffixer le nom des images par -hover, renommez vos images d’état survolé avec le suffixe _hover (avec un underscore).
Ainsi, dans mon exemple, j’ajoute dans le dossier icon les images fork_hover.png, info_hover.png, magnifer_hover.png, tag_hover.png et x_hover.png pour obtenir la CSS :
.icon-sprite, .icon-fork, .icon-info, .icon-magnifer, .icon-tag, .icon-x {
  background: url('../img/icon-s8021aff651.png') no-repeat;
}
.icon-fork {
  background-position: 0 -72px;
  height: 24px;
  width: 21px;
}
.icon-fork:hover, .icon-fork.fork_hover, .icon-fork.fork-hover {
  background-position: 0 -48px;
}
.icon-info {
  background-position: 0 -210px;
  height: 24px;
  width: 12px;
}
.icon-info:hover, .icon-info.info_hover, .icon-info.info-hover {
  background-position: 0 -186px;
}
.icon-magnifer {
  background-position: 0 -24px;
  height: 24px;
  width: 24px;
}
.icon-magnifer:hover, .icon-magnifer.magnifer_hover, .icon-magnifer.magnifer-hover {
  background-position: 0 0;
}
.icon-tag {
  background-position: 0 -120px;
  height: 24px;
  width: 24px;
}
.icon-tag:hover, .icon-tag.tag_hover, .icon-tag.tag-hover {
  background-position: 0 -96px;
}
.icon-x {
  background-position: 0 -165px;
  height: 21px;
  width: 21px;
}
.icon-x:hover, .icon-x.x_hover, .icon-x.x-hover {
  background-position: 0 -144px;
}

Bien d’autres options sont disponibles. Je vous invite à vous reporter sur la documentation pour en prendre connaissance.

Choisir le layout optimal

Depuis la version 0.12, Compass permet de choisir l’agencement (à ne pas confondre avec l’ordre) des images sprites
vertical (par défaut), horizontal, diagonal et smart.

Par défaut, les images sont empilées verticalement dans le sprites.

L’agencement smart est idéal pour les sprites dont les images sont affichées dans des éléments de type bloc, aux dimensions fixes. Attention, toute option de positionnement, d’espacement et de répétition sera tout bonnement ignorée par Compass. Normal, elles sont incompatible avec le format du sprite généré.

Exemple de sprite avec le layout smart.

Répéter horizontalement une image sprite

Lorsque la variable $<map>-<sprite>-repeat: repeat-x est définie, Compass duplique automatiquement l’image dans le sprite afin qu’elle occupe toute sa largeur !

Il faut bien différencier la déclaration de la variable $<map>-<sprite>-repeat: repeat-x de la propriété background-position: repeat-x. La première est uniquement utile au générateur de sprites. Vous devez préciser la répétition au niveau de l’élément affichant l’image de fond.

Un exemple sera plus explicite. Considérez le motif construction.png a répéter horizontalement, contenu dans le répertoire rx :

Le dossier contient une autre image plus large que la précédente :

Importez comme à l’habituel vos sprites et précisez explicitement en CSS une répétition du fond pour la classe .rx-construction :

@import "rx/*.png";
@include all-rx-sprites;
.rx-construction {
  background-repeat: repeat-x;
}

L’effet obtenu n’est pas vraiment celui escompté :

Pourquoi ? Tout simplement parce que le sprite généré est plus large que l’image construction.png. Il est alors naturel qu’un espace vide soit dupliqué en même temps que le sprite.
Jugez par vous-même, la zone bleutée marquant l’espace vide en trop :

Le vide à droite du motif empêche sa répétition.

Maintenant, supprimez le background-repeat: repeat-x et déclarez la variable $<map>-<sprite>-repeat: repeat-x avant d’importer les images du sprite (où <sprite> est le nom de l’image).

$rx-construction-repeat: repeat-x;
@import "rx/*.png";
@include all-rx-sprites;
.rx-construction {
}

À défaut d’être répétée horizontalement, vous apprécierez que Compass ait dupliqué autant de fois que nécessaire l’image dans le sprite afin d’occuper toute sa largeur !

Finalement, il vous faut bien doubler la duplication horizontale du sprite par un background-repeat: repeat-x en CSS :

$rx-construction-repeat: repeat-x;
@import "rx/*.png";
@include all-rx-sprites;
.rx-construction {
  background-repeat: repeat-x;
}

Par ailleurs, Compass veillera a ne pas couper votre image puisque si vous la répétez c’est qu’il s’agit vraisemblablement d’un motif. Le sprite final sera simplement élargi en conséquence.

L'intégrité du motif est assurée.

Maitriser les sélecteurs

Les sprites c’est le pied, ils donnent la banane mais peuvent aussi vous donner envie de jeter votre clavier contre un mur une fois le nez dans la feuille de styles produite.
La surcharge de sélecteurs est en effet à prendre avec des pincettes. Non ; avec réflexion.

Imaginez que je souhaite lister ma présence sur les réseaux sociaux à l’aide d’icônes (le truc classique donc) :

<ul class="inline">
  <li><a href="https://twitter.com/piouPiouM" class="social-twitter">@piouPiouM</a></li>
  <li><a href="https://github.com/piouPiouM" class="social-github">Github</a></li>
  <li><a href="http://fr.linkedin.com/in/mehdikabab" class="social-linkedin">Profil LinkedIn</a></li>
  <li><a href="http://www.lastfm.fr/user/piouPiouM" class="social-lastfm">J'&eacute;coute un peu de tout</a></li>
  <li><a href="#dribble" class="social-dribbble">Dribbble</a></li>
  <li><a href="#facebook" class="social-facebook">Facebook</a></li>
</ul>

Bien sûr, je veille à ce que les liens restent accessibles. En résumé, il me faut :

Le premier réflexe est de surcharger la classe .social-sprite commune à tous les sprites, comme suit :

.inline {
  // Afficher une liste horizontale.
  @include horizontal-list;
}
$social-layout: smart;           // Layout intelligent.
$social-sprite-dimensions: true; // Ajouter les dimensions de chaque sprite.
@import "social/*.png";          // Importer les images.
@include all-social-sprites;     // Générer les classes de toutes les images.
.social-sprite {                 // Sur la classe commune je :
  @include hide-text;            //   - masque le texte de façon accessible ;
  @include opacity(.5);          //   - réduit l'opacité de l'élément (compatible IE6+)
  display: block;                //   - donne un affichage de type bloc.
  &:hover {                      // et au survol
    @include opacity(1);         // l'opacité est pleine.
  }
}

Nickel, ça fonctionne \o/

Sauf qu’en s’attardant sur le CSS généré je remarque que Compass ne se contente pas de surcharger la classe commune .social-sprite mais toutes les classes images. Irk.

.social-sprite, .social-dribbble, .social-facebook, .social-github,
.social-lastfm, .social-linkedin, .social-twitter {
  background: url('../img/social-s0f4871a7bd.png') no-repeat;
}
.social-dribbble {
  background-position: 0 0;
  height: 36px;
  width: 36px;
}
.social-facebook {
  background-position: 0 -36px;
  height: 36px;
  width: 36px;
}
.social-github {
  background-position: 0 -72px;
  height: 36px;
  width: 36px;
}
.social-lastfm {
  background-position: 0 -108px;
  height: 36px;
  width: 36px;
}
.social-linkedin {
  background-position: 0 -144px;
  height: 36px;
  width: 36px;
}
.social-twitter {
  background-position: 0 -180px;
  height: 36px;
  width: 36px;
}
.social-sprite, .social-dribbble, .social-facebook, .social-github,
.social-lastfm, .social-linkedin, .social-twitter {
  text-indent: -119988px;
  overflow: hidden;
  text-align: left;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
  opacity: 0.7;
  display: block;
}
.social-sprite:hover, .social-dribbble:hover, .social-facebook:hover,
.social-github:hover, .social-lastfm:hover, .social-linkedin:hover
.social-twitter:hover {
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}

Après réflexion, les développeurs de Compass ne peuvent affirmer que je vais déclarer la classe .social-sprite sur tous mes éléments HTML. D’ailleurs, je ne l’ai naturellement pas fait, comme quoi…
Tiens, et pourquoi ne déclare-t’il pas une seule et unique fois les dimensions de mes sprites alors qu’elles sont identiques ? >_<

Ok, je change d’approche pour adopter celle de Twitter Bootstrap avant que le framework ne s’appuie sur une @font-face. J’en profite pour améliorer la gestion des dimensions.

$social-layout: smart;
$social-sprite-dimensions: false; // Ne pas inclure les dimensions.
@import "social/*.png";
@include all-social-sprites;
// 
$social-map: sprite-map("social/*.png") 
// Je cible tous les éléments ayant une classe avec pour préfixe `social-`.
[class*="social-"] {
  @include hide-text;
  @include opacity(.5);
  @include sprite-dimensions($social-map, 'twitter');
  display: block;
  &:hover {
    @include opacity(1);
  }
}

Le rendu est inchangé, super.

La feuille de style, elle s’est considérablement allégée :

.social2-sprite, .social2-dribbble, .social2-facebook, .social2-github,
.social2-lastfm, .social2-linkedin, .social2-twitter {
  background: url('../img/social2-s73f312d7a9.png') no-repeat;
}
.social2-dribbble {
  background-position: 0 0;
}
.social2-facebook {
  background-position: 0 -36px;
}
.social2-github {
  background-position: 0 -72px;
}
.social2-lastfm {
  background-position: 0 -108px;
}
.social2-linkedin {
  background-position: 0 -144px;
}
.social2-twitter {
  background-position: 0 -180px;
}
[class*="social2-"] {
  text-indent: -119988px;
  overflow: hidden;
  text-align: left;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: 0.5;
  height: 36px;
  width: 36px;
  display: block;
}
[class*="social2-"]:hover {
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}

Fini les sélecteurs inutiles !

Notez l’appel au mixin sprite-dimensions() qui appel successivement à ma place les mixins créés à la volée <map>-sprite-height('<image>') et <map>-sprite-width('<image>'). Pour y avoir accès j’ai dû instancier une variable de mapping via la fonction sprite-map().

Peut-être me trouvez-vous alarmiste, mais imaginez le résultat avec 50 icônes ou plus… Aller, pour l’exemple voici ce que vous obtiendriez en transformant les icônes du pack Glyphicons en sprite avec la première méthode (et je vous épargne les déclarations de base) :

.glyphicon-sprite, .glyphicon-adjust, .glyphicon-adjust2, .glyphicon-adress_book, .glyphicon-airplane, .glyphicon-alarm,
.glyphicon-albums, .glyphicon-align_center, .glyphicon-align_left, .glyphicon-align_right, .glyphicon-amazon,
.glyphicon-anchor, .glyphicon-announcement, .glyphicon-asterisk, .glyphicon-attach, .glyphicon-ax, .glyphicon-ban,
.glyphicon-bank, .glyphicon-barcode, .glyphicon-baseball, .glyphicon-beach_umbrella, .glyphicon-beer, .glyphicon-behance,
.glyphicon-bell, .glyphicon-bin, .glyphicon-binoculars, .glyphicon-birthday_cake, .glyphicon-blog, .glyphicon-blogger,
.glyphicon-bluetooth, .glyphicon-boat, .glyphicon-bold, .glyphicon-bomb, .glyphicon-book, .glyphicon-book_open,
.glyphicon-bookmark, .glyphicon-bowling, .glyphicon-bp, .glyphicon-briefcase, .glyphicon-brightness_increase,
.glyphicon-brightness_reduce, .glyphicon-brush, .glyphicon-bullets, .glyphicon-buoy, .glyphicon-bus, .glyphicon-buzz,
.glyphicon-cake, .glyphicon-calculator, .glyphicon-calendar, .glyphicon-camera, .glyphicon-camera_small, .glyphicon-candle,
.glyphicon-car, .glyphicon-cardio, .glyphicon-cargo, .glyphicon-cars, .glyphicon-cart_in, .glyphicon-cart_out,
.glyphicon-celebration, .glyphicon-certificate, .glyphicon-charts, .glyphicon-chat, .glyphicon-check, .glyphicon-circle_arrow_down,
.glyphicon-circle_arrow_left, .glyphicon-circle_arrow_right, .glyphicon-circle_arrow_top, .glyphicon-circle_exclamation_mark,
.glyphicon-circle_info, .glyphicon-circle_minus, .glyphicon-circle_ok, .glyphicon-circle_plus, .glyphicon-circle_question_mark,
.glyphicon-circle_remove, .glyphicon-cleaning, .glyphicon-clock, .glyphicon-cloud, .glyphicon-coffe_cup, .glyphicon-cogwheel,
.glyphicon-cogwheels, .glyphicon-comments, .glyphicon-compass, .glyphicon-computer_locked, .glyphicon-computer_proces, .glyphicon-computer_service,
.glyphicon-conversation, .glyphicon-credit, .glyphicon-credit_card, .glyphicon-crop, .glyphicon-cup, .glyphicon-cutlery, .glyphicon-dashboard,
.glyphicon-database_ban, .glyphicon-database_lock, .glyphicon-database_minus, .glyphicon-database_plus, .glyphicon-delete_point, .glyphicon-deviantart,
.glyphicon-direction, .glyphicon-dislikes, .glyphicon-display, .glyphicon-divide, .glyphicon-dog, .glyphicon-down_arrow, .glyphicon-download,
.glyphicon-download_alt, .glyphicon-dribbble, .glyphicon-drink, .glyphicon-dropbox, .glyphicon-dumbbell, .glyphicon-ear_plugs, .glyphicon-edit, .glyphicon-eject,
.glyphicon-electrical_plug, .glyphicon-electrical_socket_eu, .glyphicon-electrical_socket_us, .glyphicon-electricity, .glyphicon-email, .glyphicon-embed,
.glyphicon-embed_close, .glyphicon-envelope, .glyphicon-euro, .glyphicon-evernote, .glyphicon-eye_close, .glyphicon-eye_open, .glyphicon-fabric,
.glyphicon-facebook, .glyphicon-facetime_video, .glyphicon-fast_backward, .glyphicon-fast_food, .glyphicon-fast_forward, .glyphicon-female, .glyphicon-file,
.glyphicon-file_export, .glyphicon-file_import, .glyphicon-film, .glyphicon-filter, .glyphicon-fins, .glyphicon-fire, .glyphicon-fishes, .glyphicon-flag,
.glyphicon-flash, .glyphicon-flickr, .glyphicon-flower, .glyphicon-folder_flag, .glyphicon-folder_lock, .glyphicon-folder_minus, .glyphicon-folder_new,
.glyphicon-folder_open, .glyphicon-folder_plus, .glyphicon-font, .glyphicon-forrst, .glyphicon-forward, .glyphicon-french_press, .glyphicon-fullscreen,
.glyphicon-gamepad, .glyphicon-gift, .glyphicon-girl, .glyphicon-github, .glyphicon-glass, .glyphicon-globe, .glyphicon-google_alt, .glyphicon-google_maps,
.glyphicon-google_plus, .glyphicon-grater, .glyphicon-group, .glyphicon-hand_down, .glyphicon-hand_left, .glyphicon-hand_right, .glyphicon-hand_up, .glyphicon-hdd,
.glyphicon-headphones, .glyphicon-headset, .glyphicon-heart, .glyphicon-heat, .glyphicon-history, .glyphicon-home, .glyphicon-hospital, .glyphicon-hospital_h,
.glyphicon-imac, .glyphicon-inbox, .glyphicon-inbox_in, .glyphicon-inbox_lock, .glyphicon-inbox_minus, .glyphicon-inbox_out, .glyphicon-inbox_plus, .glyphicon-instapaper,
.glyphicon-ipad, .glyphicon-iphone, .glyphicon-iphone_exchange, .glyphicon-iphone_shake, .glyphicon-iphone_transfer, .glyphicon-ipod, .glyphicon-ipod_shuffle,
.glyphicon-italic, .glyphicon-jolicloud, .glyphicon-justify, .glyphicon-kettle, .glyphicon-keyboard_wired, .glyphicon-keyboard_wireless, .glyphicon-keynote, .glyphicon-keys,
.glyphicon-last_fm, .glyphicon-leaf, .glyphicon-leather, .glyphicon-left_arrow, .glyphicon-left_indent, .glyphicon-lightbulb, .glyphicon-link, .glyphicon-linked_in,
.glyphicon-list, .glyphicon-lock, .glyphicon-log_book, .glyphicon-luggage, .glyphicon-macbook, .glyphicon-magic, .glyphicon-magnet, .glyphicon-male, .glyphicon-message_ban,
.glyphicon-message_empty, .glyphicon-message_flag, .glyphicon-message_full, .glyphicon-message_in, .glyphicon-message_lock, .glyphicon-message_minus, .glyphicon-message_new,
.glyphicon-message_out, .glyphicon-message_plus, .glyphicon-microphone, .glyphicon-moon, .glyphicon-more, .glyphicon-more_windows, .glyphicon-moreitems, .glyphicon-move,
.glyphicon-music, .glyphicon-mute, .glyphicon-nameplate, .glyphicon-nameplate_alt, .glyphicon-new_window, .glyphicon-note, .glyphicon-notes, .glyphicon-notes_2, .glyphicon-ok,
.glyphicon-ok_2, .glyphicon-old_man, .glyphicon-oxygen_bottle, .glyphicon-pants, .glyphicon-parents, .glyphicon-pause, .glyphicon-pen, .glyphicon-pencil, .glyphicon-phone,
.glyphicon-piano, .glyphicon-picasa, .glyphicon-picture, .glyphicon-pie_chart, .glyphicon-pin, .glyphicon-pin_classic, .glyphicon-pin_flag, .glyphicon-pinboard, .glyphicon-pinterest,
.glyphicon-pizza, .glyphicon-play, .glyphicon-play_button, .glyphicon-playing_dices, .glyphicon-playlist, .glyphicon-podium, .glyphicon-pool, .glyphicon-pot, .glyphicon-power,
.glyphicon-print, .glyphicon-projector, .glyphicon-qrcode, .glyphicon-quora, .glyphicon-rabbit, .glyphicon-random, .glyphicon-read_it_later, .glyphicon-readability,
.glyphicon-refresh, .glyphicon-remove, .glyphicon-remove_2, .glyphicon-repeat, .glyphicon-resize_full, .glyphicon-resize_small, .glyphicon-retweet, .glyphicon-retweet_2,
.glyphicon-rewind, .glyphicon-riflescope, .glyphicon-right_arrow, .glyphicon-right_indent, .glyphicon-ring, .glyphicon-road, .glyphicon-rotation_lock, .glyphicon-roundabout,
.glyphicon-router, .glyphicon-rss, .glyphicon-rugby, .glyphicon-ruller, .glyphicon-sampler, .glyphicon-scissors, .glyphicon-screenshot, .glyphicon-scuba_diving, .glyphicon-search,
.glyphicon-settings, .glyphicon-share, .glyphicon-share2, .glyphicon-sheriffs_star, .glyphicon-shield, .glyphicon-shopping_bag, .glyphicon-shopping_cart, .glyphicon-show_big_thumbnails,
.glyphicon-show_lines, .glyphicon-show_thumbnails, .glyphicon-show_thumbnails_with_lines, .glyphicon-signal, .glyphicon-signal2, .glyphicon-skitch, .glyphicon-skull, .glyphicon-skype,
.glyphicon-snorkel_diving, .glyphicon-snowflake, .glyphicon-sort, .glyphicon-spade, .glyphicon-spootify, .glyphicon-square, .glyphicon-star, .glyphicon-stats, .glyphicon-step_backward,
.glyphicon-step_forward, .glyphicon-stop, .glyphicon-stopwatch, .glyphicon-stroller, .glyphicon-stumbleupon, .glyphicon-suitcase, .glyphicon-sun, .glyphicon-sweater, .glyphicon-table,
.glyphicon-table_tennis, .glyphicon-tablet, .glyphicon-tag, .glyphicon-tags, .glyphicon-tea_kettle, .glyphicon-temple_buddhist, .glyphicon-temple_christianity_church, .glyphicon-temple_hindu,
.glyphicon-temple_islam, .glyphicon-text_bigger, .glyphicon-text_height, .glyphicon-text_resize, .glyphicon-text_smaller, .glyphicon-text_strike, .glyphicon-text_underline, .glyphicon-text_width,
.glyphicon-thin_arrow_left, .glyphicon-thin_right_arrow, .glyphicon-thumbs_down, .glyphicon-thumbs_up, .glyphicon-tie, .glyphicon-tint, .glyphicon-train, .glyphicon-tree_conifer,
.glyphicon-tree_deciduous, .glyphicon-truck, .glyphicon-tshirt, .glyphicon-tumblr, .glyphicon-turtle, .glyphicon-twitter, .glyphicon-twitter_t, .glyphicon-umbrella, .glyphicon-unlock,
.glyphicon-unshare, .glyphicon-up_arrow, .glyphicon-upload, .glyphicon-usd, .glyphicon-user, .glyphicon-user_add, .glyphicon-user_remove, .glyphicon-vases, .glyphicon-vcard,
.glyphicon-vector_path_all, .glyphicon-vector_path_circle, .glyphicon-vector_path_curve, .glyphicon-vector_path_line, .glyphicon-vector_path_polygon, .glyphicon-vector_path_square,
.glyphicon-vimeo, .glyphicon-volume_down, .glyphicon-volume_up, .glyphicon-wallet, .glyphicon-warning_sign, .glyphicon-web_browser, .glyphicon-webcam, .glyphicon-wifi_alt, .glyphicon-woman,
.glyphicon-wordpress, .glyphicon-xing, .glyphicon-yahoo, .glyphicon-youtube, .glyphicon-zoom_in, .glyphicon-zoom_out, .glyphicon-zootool {
  text-indent: -119988px;
  overflow: hidden;
  text-align: left;
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: 0.5;
  display: block;
}
.glyphicon-sprite:hover .glyphicon-adjust:hover .glyphicon-adjust2:hover .glyphicon-adress_book:hover .glyphicon-airplane:hover .glyphicon-alarm:hover
.glyphicon-albums:hover .glyphicon-align_center:hover .glyphicon-align_left:hover .glyphicon-align_right:hover .glyphicon-amazon:hover
.glyphicon-anchor:hover .glyphicon-announcement:hover .glyphicon-asterisk:hover .glyphicon-attach:hover .glyphicon-ax:hover .glyphicon-ban:hover
.glyphicon-bank:hover .glyphicon-barcode:hover .glyphicon-baseball:hover .glyphicon-beach_umbrella:hover .glyphicon-beer:hover .glyphicon-behance:hover
.glyphicon-bell:hover .glyphicon-bin:hover .glyphicon-binoculars:hover .glyphicon-birthday_cake:hover .glyphicon-blog:hover .glyphicon-blogger:hover
.glyphicon-bluetooth:hover .glyphicon-boat:hover .glyphicon-bold:hover .glyphicon-bomb:hover .glyphicon-book:hover .glyphicon-book_open:hover
.glyphicon-bookmark:hover .glyphicon-bowling:hover .glyphicon-bp:hover .glyphicon-briefcase:hover .glyphicon-brightness_increase:hover
.glyphicon-brightness_reduce:hover .glyphicon-brush:hover .glyphicon-bullets:hover .glyphicon-buoy:hover .glyphicon-bus:hover .glyphicon-buzz:hover
.glyphicon-cake:hover .glyphicon-calculator:hover .glyphicon-calendar:hover .glyphicon-camera:hover .glyphicon-camera_small:hover .glyphicon-candle:hover
.glyphicon-car:hover .glyphicon-cardio:hover .glyphicon-cargo:hover .glyphicon-cars:hover .glyphicon-cart_in:hover .glyphicon-cart_out:hover
.glyphicon-celebration:hover .glyphicon-certificate:hover .glyphicon-charts:hover .glyphicon-chat:hover .glyphicon-check:hover .glyphicon-circle_arrow_down:hover
.glyphicon-circle_arrow_left:hover .glyphicon-circle_arrow_right:hover .glyphicon-circle_arrow_top:hover .glyphicon-circle_exclamation_mark:hover
.glyphicon-circle_info:hover .glyphicon-circle_minus:hover .glyphicon-circle_ok:hover .glyphicon-circle_plus:hover .glyphicon-circle_question_mark:hover
.glyphicon-circle_remove:hover .glyphicon-cleaning:hover .glyphicon-clock:hover .glyphicon-cloud:hover .glyphicon-coffe_cup:hover .glyphicon-cogwheel:hover
.glyphicon-cogwheels:hover .glyphicon-comments:hover .glyphicon-compass:hover .glyphicon-computer_locked:hover .glyphicon-computer_proces:hover .glyphicon-computer_service:hover
.glyphicon-conversation:hover .glyphicon-credit:hover .glyphicon-credit_card:hover .glyphicon-crop:hover .glyphicon-cup:hover .glyphicon-cutlery:hover .glyphicon-dashboard:hover
.glyphicon-database_ban:hover .glyphicon-database_lock:hover .glyphicon-database_minus:hover .glyphicon-database_plus:hover .glyphicon-delete_point:hover .glyphicon-deviantart:hover
.glyphicon-direction:hover .glyphicon-dislikes:hover .glyphicon-display:hover .glyphicon-divide:hover .glyphicon-dog:hover .glyphicon-down_arrow:hover .glyphicon-download:hover
.glyphicon-download_alt:hover .glyphicon-dribbble:hover .glyphicon-drink:hover .glyphicon-dropbox:hover .glyphicon-dumbbell:hover .glyphicon-ear_plugs:hover .glyphicon-edit:hover .glyphicon-eject:hover
.glyphicon-electrical_plug:hover .glyphicon-electrical_socket_eu:hover .glyphicon-electrical_socket_us:hover .glyphicon-electricity:hover .glyphicon-email:hover .glyphicon-embed:hover
.glyphicon-embed_close:hover .glyphicon-envelope:hover .glyphicon-euro:hover .glyphicon-evernote:hover .glyphicon-eye_close:hover .glyphicon-eye_open:hover .glyphicon-fabric:hover
.glyphicon-facebook:hover .glyphicon-facetime_video:hover .glyphicon-fast_backward:hover .glyphicon-fast_food:hover .glyphicon-fast_forward:hover .glyphicon-female:hover .glyphicon-file:hover
.glyphicon-file_export:hover .glyphicon-file_import:hover .glyphicon-film:hover .glyphicon-filter:hover .glyphicon-fins:hover .glyphicon-fire:hover .glyphicon-fishes:hover .glyphicon-flag:hover
.glyphicon-flash:hover .glyphicon-flickr:hover .glyphicon-flower:hover .glyphicon-folder_flag:hover .glyphicon-folder_lock:hover .glyphicon-folder_minus:hover .glyphicon-folder_new:hover
.glyphicon-folder_open:hover .glyphicon-folder_plus:hover .glyphicon-font:hover .glyphicon-forrst:hover .glyphicon-forward:hover .glyphicon-french_press:hover .glyphicon-fullscreen:hover
.glyphicon-gamepad:hover .glyphicon-gift:hover .glyphicon-girl:hover .glyphicon-github:hover .glyphicon-glass:hover .glyphicon-globe:hover .glyphicon-google_alt:hover .glyphicon-google_maps:hover
.glyphicon-google_plus:hover .glyphicon-grater:hover .glyphicon-group:hover .glyphicon-hand_down:hover .glyphicon-hand_left:hover .glyphicon-hand_right:hover .glyphicon-hand_up:hover .glyphicon-hdd:hover
.glyphicon-headphones:hover .glyphicon-headset:hover .glyphicon-heart:hover .glyphicon-heat:hover .glyphicon-history:hover .glyphicon-home:hover .glyphicon-hospital:hover .glyphicon-hospital_h:hover
.glyphicon-imac:hover .glyphicon-inbox:hover .glyphicon-inbox_in:hover .glyphicon-inbox_lock:hover .glyphicon-inbox_minus:hover .glyphicon-inbox_out:hover .glyphicon-inbox_plus:hover .glyphicon-instapaper:hover
.glyphicon-ipad:hover .glyphicon-iphone:hover .glyphicon-iphone_exchange:hover .glyphicon-iphone_shake:hover .glyphicon-iphone_transfer:hover .glyphicon-ipod:hover .glyphicon-ipod_shuffle:hover
.glyphicon-italic:hover .glyphicon-jolicloud:hover .glyphicon-justify:hover .glyphicon-kettle:hover .glyphicon-keyboard_wired:hover .glyphicon-keyboard_wireless:hover .glyphicon-keynote:hover .glyphicon-keys:hover
.glyphicon-last_fm:hover .glyphicon-leaf:hover .glyphicon-leather:hover .glyphicon-left_arrow:hover .glyphicon-left_indent:hover .glyphicon-lightbulb:hover .glyphicon-link:hover .glyphicon-linked_in:hover
.glyphicon-list:hover .glyphicon-lock:hover .glyphicon-log_book:hover .glyphicon-luggage:hover .glyphicon-macbook:hover .glyphicon-magic:hover .glyphicon-magnet:hover .glyphicon-male:hover .glyphicon-message_ban:hover
.glyphicon-message_empty:hover .glyphicon-message_flag:hover .glyphicon-message_full:hover .glyphicon-message_in:hover .glyphicon-message_lock:hover .glyphicon-message_minus:hover .glyphicon-message_new:hover
.glyphicon-message_out:hover .glyphicon-message_plus:hover .glyphicon-microphone:hover .glyphicon-moon:hover .glyphicon-more:hover .glyphicon-more_windows:hover .glyphicon-moreitems:hover .glyphicon-move:hover
.glyphicon-music:hover .glyphicon-mute:hover .glyphicon-nameplate:hover .glyphicon-nameplate_alt:hover .glyphicon-new_window:hover .glyphicon-note:hover .glyphicon-notes:hover .glyphicon-notes_2:hover .glyphicon-ok:hover
.glyphicon-ok_2:hover .glyphicon-old_man:hover .glyphicon-oxygen_bottle:hover .glyphicon-pants:hover .glyphicon-parents:hover .glyphicon-pause:hover .glyphicon-pen:hover .glyphicon-pencil:hover .glyphicon-phone:hover
.glyphicon-piano:hover .glyphicon-picasa:hover .glyphicon-picture:hover .glyphicon-pie_chart:hover .glyphicon-pin:hover .glyphicon-pin_classic:hover .glyphicon-pin_flag:hover .glyphicon-pinboard:hover .glyphicon-pinterest:hover
.glyphicon-pizza:hover .glyphicon-play:hover .glyphicon-play_button:hover .glyphicon-playing_dices:hover .glyphicon-playlist:hover .glyphicon-podium:hover .glyphicon-pool:hover .glyphicon-pot:hover .glyphicon-power:hover
.glyphicon-print:hover .glyphicon-projector:hover .glyphicon-qrcode:hover .glyphicon-quora:hover .glyphicon-rabbit:hover .glyphicon-random:hover .glyphicon-read_it_later:hover .glyphicon-readability:hover
.glyphicon-refresh:hover .glyphicon-remove:hover .glyphicon-remove_2:hover .glyphicon-repeat:hover .glyphicon-resize_full:hover .glyphicon-resize_small:hover .glyphicon-retweet:hover .glyphicon-retweet_2:hover
.glyphicon-rewind:hover .glyphicon-riflescope:hover .glyphicon-right_arrow:hover .glyphicon-right_indent:hover .glyphicon-ring:hover .glyphicon-road:hover .glyphicon-rotation_lock:hover .glyphicon-roundabout:hover
.glyphicon-router:hover .glyphicon-rss:hover .glyphicon-rugby:hover .glyphicon-ruller:hover .glyphicon-sampler:hover .glyphicon-scissors:hover .glyphicon-screenshot:hover .glyphicon-scuba_diving:hover .glyphicon-search:hover
.glyphicon-settings:hover .glyphicon-share:hover .glyphicon-share2:hover .glyphicon-sheriffs_star:hover .glyphicon-shield:hover .glyphicon-shopping_bag:hover .glyphicon-shopping_cart:hover .glyphicon-show_big_thumbnails:hover
.glyphicon-show_lines:hover .glyphicon-show_thumbnails:hover .glyphicon-show_thumbnails_with_lines:hover .glyphicon-signal:hover .glyphicon-signal2:hover .glyphicon-skitch:hover .glyphicon-skull:hover .glyphicon-skype:hover
.glyphicon-snorkel_diving:hover .glyphicon-snowflake:hover .glyphicon-sort:hover .glyphicon-spade:hover .glyphicon-spootify:hover .glyphicon-square:hover .glyphicon-star:hover .glyphicon-stats:hover .glyphicon-step_backward:hover
.glyphicon-step_forward:hover .glyphicon-stop:hover .glyphicon-stopwatch:hover .glyphicon-stroller:hover .glyphicon-stumbleupon:hover .glyphicon-suitcase:hover .glyphicon-sun:hover .glyphicon-sweater:hover .glyphicon-table:hover
.glyphicon-table_tennis:hover .glyphicon-tablet:hover .glyphicon-tag:hover .glyphicon-tags:hover .glyphicon-tea_kettle:hover .glyphicon-temple_buddhist:hover .glyphicon-temple_christianity_church:hover .glyphicon-temple_hindu:hover
.glyphicon-temple_islam:hover .glyphicon-text_bigger:hover .glyphicon-text_height:hover .glyphicon-text_resize:hover .glyphicon-text_smaller:hover .glyphicon-text_strike:hover .glyphicon-text_underline:hover .glyphicon-text_width:hover
.glyphicon-thin_arrow_left:hover .glyphicon-thin_right_arrow:hover .glyphicon-thumbs_down:hover .glyphicon-thumbs_up:hover .glyphicon-tie:hover .glyphicon-tint:hover .glyphicon-train:hover .glyphicon-tree_conifer:hover
.glyphicon-tree_deciduous:hover .glyphicon-truck:hover .glyphicon-tshirt:hover .glyphicon-tumblr:hover .glyphicon-turtle:hover .glyphicon-twitter:hover .glyphicon-twitter_t:hover .glyphicon-umbrella:hover .glyphicon-unlock:hover
.glyphicon-unshare:hover .glyphicon-up_arrow:hover .glyphicon-upload:hover .glyphicon-usd:hover .glyphicon-user:hover .glyphicon-user_add:hover .glyphicon-user_remove:hover .glyphicon-vases:hover .glyphicon-vcard:hover
.glyphicon-vector_path_all:hover .glyphicon-vector_path_circle:hover .glyphicon-vector_path_curve:hover .glyphicon-vector_path_line:hover .glyphicon-vector_path_polygon:hover .glyphicon-vector_path_square:hover
.glyphicon-vimeo:hover .glyphicon-volume_down:hover .glyphicon-volume_up:hover .glyphicon-wallet:hover .glyphicon-warning_sign:hover .glyphicon-web_browser:hover .glyphicon-webcam:hover .glyphicon-wifi_alt:hover .glyphicon-woman:hover
.glyphicon-wordpress:hover .glyphicon-xing:hover .glyphicon-yahoo:hover .glyphicon-youtube:hover .glyphicon-zoom_in:hover .glyphicon-zoom_out:hover .glyphicon-zootool:hover {
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  opacity: 1;
}

Allez, vous pouvez remonter sur votre chaise ;-)
Ce n’est pas moins de 800 sélecteurs qui ont étés générés alors que 2 suffisent pour achever la même tâche.