CSS : background position

On a beau défendre les recommandations W3C pour tout ce qui est languages web, il y a des fois où des implémentations propriétaires sont bien utiles. Exmple avec la propriété CSS background-position.

Icônes

Image mosaïque consituée d'« icônes ».

Imaginons que nous ayons une liste d'items (ci-dessous) dont nous souhaitons remplacer le texte par une icône, icône qui changera lorsque l'utilisateur passe la souris au-dessus. C'est quelque chose d'assez courant à faire et de nombreuses techniques existent pour créer ce genre d'effet. Imaginons que nous utilisions une image mosaïque ou « sprite » pour stocker toutes les icônes, à l'état normal et à l'état survolé (voir image ci-contre). Voilà ce à quoi on pourrait aboutir :

<ul>
    <li><a href="/foo/">Foo</a></li>
    <li><a href="/bar/">Bar</a></li>
    <li><a href="/baz/">Baz</a></li>
</ul>
Code HTML d'une liste d'items à transformer en icônes.
ul {
    overflow: hidden;
}
li {
    float: left;
    list-style: none;
}
a {
    display: block;
    width: 16px;
    height: 16px;
    font-size: 0;
    background-image: url(icons.png);
    background-repeat: no-repeat;
}
/* icônes par défaut */
a[href='/foo/'] { background-position: 0 0; }
a[href='/bar/'] { background-position: 0 -16px; }
a[href='/baz/'] { background-position: 0 -32px; }
/* icônes pour le hover */
a[href='/foo/']:hover { background-position: -16px 0; }
a[href='/bar/']:hover { background-position: -16px -16px; }
a[href='/baz/']:hover { background-position: -16px -32px; }
Code CSS pour transformer les items de liste en icônes.
Rendu des items de liste sous forme d'icônes.

Nous voyons le principe de la chose : tous les items utilisent la même image de fond mais positionée de différentes manières. Idem pour l'effet hover où nous devons décaler la position horizontal de 16px.

C'est gérable quand vous n'avez que quelques éléments à styliser, mais quand il y en a beaucoup, disons plus de 10… On aimerait dés lors avoir la possibilité de définir une seule coordonnée de position(1) afin de gérer par exemple l'effet hover à l'aide d'une unique règle CSS. Pourquoi cela n'est-il pas possible ?

En rédigeant cette note, je suis tombé sur un billet de Johnathan Snook parlant de deux propriétés propriétaires d'Internet Explorer (implémentée aussi par Chromium) qui répondent exactement à ce type de besoin, background-position-x et background-position-y. Changer l'icône d'illustration des items de liste quand la souris passe dessus est alors très simple :

/* Icônes pour le hover */
a:hover { background-position-x: -16px; }
Utilisation de la propriété propriétaire background-position-x.
Rendu des items de liste sous forme d'icônes (uniquement sous Internet Explorer et Chrome).

Pourquoi ces deux propriétés ont-elles été réfusées pour intégration dans les recommandations CSS 2.1, alors qu'elles facilitent grandement le travail de développeur ? Il existe évidemment des techniques de contournement, mais cela nécessite d'utiliser au moins 2 fichiers image, ce qui n'est pas idéal(2).

SNOOK, Johnathan. Background Position X and Y. snook.ca,

BOS, Bert ; ETEMAD, Elika ; KEMPER, Brad. CSS Backgrounds and Borders Module Level 3. W3C, . 3.6. The background-position property