Sélection de la langue

Français

Flux sur le design

Home > Technologie > Langages > Décorer des éléments de taille variable
Décorer des éléments de taille variable
Technologie - Langages
Écrit par J.-N. R.   
Lundi, 17 Mai 2010 09:37

Une technique CSS 2 pour décorer des éléments de taille variable.

De manière étonnante, ajouter des décorations aux éléments de taille variable est très difficile en CSS 2.1. C'est beaucoup plus facile en CSS 3 avec le module Fond et Contours (Backgrounds and Borders). Mais pour faire une page qui s'affiche correctement sur les versions actuellement utilisées d'Internet Explorer (les versions 6, 7, et 8 constituent 60% de la totalité des requêtes Web en Juin 2010), on se retrouve avec CSS 2.1 et un sacré problème sur les bras. Cet article explique pourquoi le problème des éléments à taille variable est difficile, et propose une technique pour le résoudre. Cette technique n'utilise aucun truc Javascript ; que du CSS et de l'HTML conformes aux standards W3C, avec quelques images.

1. Le problème fondamental

Si on regarde les sites Web actuels (2010), on se rend compte que la plupart des designers du web utilisent encore des images pour décorer les éléments du site. Prenons un exemple simple mais omniprésent : les coins arrondis. Comme ils n'existent pas en CSS 2.1 (au contraire de CSS 3), 90% des sites utilisent une image de fond pour produire cet effet. Cette image de fond est facile à produire lorsque l'élément à décorer est de taille fixe (hauteur et largeur): lancez GIMP ou Photoshop, créez une nouvelle image de la taille de votre élément, peignez la de la couleur de fond choisie et ensuite ajoutez les coins arrondis (voir ce lien pour un tutoriel GIMP ; c'est très facile). Dans le CSS, ajoutez la propriété background-image à votre élément et c'est fini.

Mais que faire lorsque l'élément n'a pas une largeur fixe de 200 pixels, mais une largeur variable qui dépend de son contenu ou de la taille de l'écran ? Cela arrive très souvent mais rend le problème beaucoup plus difficile. On ne peut plus utiliser une image de fond, puisqu'elle n'aurait presque jamais la taille de l'élément. Pour vous convaincre, regardez les boutons suivants : le premier a une largeur d'environ 100 pixels . Mais le second a un texte plus grand, et la première image ne va donc plus du tout . Paver le fond avec l'image ne résout évidemment rien . Et il est bien sur très ennuyeux de générer une image pour chaque texte de bouton qui est sur votre site (cela rendrait également le code CSS sale, avec une ID pour chaque bouton alors qu'une même classe pour tous aurait du suffire). Comment résoudre ce problème?

2. Une solution générique

La solution suivante est un peu complexe, mais règle le problème même dans le pire cas, celui d'un élément de hauteur et de largeur inconnue. Son désavantage principal est de rajouter pas mal de code HTML à l'élément d'origine. Mais jusqu'à ce que CSS 3 soit utilisable en production, cette méthode reste probablement la meilleure.

Nous devons d'abord ajouter 9 (oui, 9!) sous-divisions à notre élément d'origine. En effet, il nous faut 4 divisions pour les coins, 4 pour les bords et une pour le fond au centre. Au final, le HTML ressemblera à ça:

This is our text


Ensuite nous devons écrire le CSS adapté. L'idée est d'utiliser le positionnement absolu pour nos divs, et comme nous voulons les placer par rapport à l'élément d'origine, celui-ci doit former une nouvelle boîte. La façon la plus simple d'en faire une nouvelle boîte est de lui ajouter la propriété CSS position: relative. Une fois ceci fait, il ne manque plus que le CSS pour les autres éléments :

 

#originalElement .BackgroundDecoration
{
background-color: #4a93de;
top: 8px;
bottom: 8px;
left: 0px;
right: 0px;
position: absolute;
}

#originalElement .TopLeftDecoration
{
top: 0px;
left: 0px;
height: 8px;
width: 8px;
background-repeat: no-repeat;
background-image: url("rounded-corner-top-left.png");
position: absolute;
}

#originalElement .TopRightDecoration
{
top: 0px;
right: 0px;
height: 8px;
width: 8px;
background-repeat: no-repeat;
background-image: url("rounded-corner-top-right.png");
position: absolute;
}

#originalElement .BottomLeftDecoration
{
bottom: 0px;
left: 0px;
height: 8px;
width: 8px;
background-repeat: no-repeat;
background-image: url("rounded-corner-bottom-left.png");
position: absolute;
}

#originalElement .BottomRightDecoration
{
bottom: 0px;
right: 0px;
height: 8px;
width: 8px;
background-repeat: no-repeat;
background-image: url("rounded-corner-bottom-right.png");
position: absolute;
}

#originalElement .TopDecoration
{
background-color: #4a93de;
height: 8px;
left: 8px;
right: 8px;
position: absolute;
}

#originalElement .BottomDecoration
{
background-color: #4a93de;
height: 8px;
left: 8px;
right: 8px;
position: absolute;
}

#originalElement .LeftDecoration
{
background-color: #4a93de;
width: 8px;
top: 8px;
bottom: 8px;
position: absolute;
}

#originalElement .RightDecoration
{
background-color: #4a93de;
width: 8px;
top: 8px;
bottom: 8px;
position: absolute;
}

Ce code suppose que nous avons créé des coins arrondis d'un rayon de 8 pixel (les divisions aux coins feront 8*8 pixels), avec #4a93de comme couleur de fond. Vous devrez probablement aussi rajouter une marge intérieure (padding) à l'élément d'origine pour que le contenu ait une meilleure allure (je recommande le même padding que le rayon du coin arrondi : 8 pixels). Le CSS ci-dessus parle de lui même, mais il faut le regarder de près pour comprendre comment s'emboîtent les pièces.

Par exemple, vous questionnez peut-être la nécessité d'avoir 4 divs pour les bords (gauche, droite, haut et bas) et une pour le fond. C'est obligatoire si vous utilisez des PNGs transparents. Si vous essayez de mettre la propriété background-color directement sur l'élément d'origine, vous vous rendrez compte que l'extérieur des coins arrondis n'est pas beau, car la couleur de fond de l'élément d'origine apparaîtra sous la partie transparente des coins. Si vous utilisez une image sans transparence (donc en mettant la couleur de l'extérieur des coins arrondis à la couleur du reste de la page), vous pouvez vous en sortir en ne mettant que quatre divs pour les coins. Je suggère tout de même d'utiliser 9 divs, car cela rend la solution beaucoup plus générique. Si vous changez la couleur de fond de la page plus tard, vous n'aurez pas à recréer vos coins.

Voici quelques résultats obtenus en utilisant cette technique. Comme vous pouvez le voir, on peut créer autant de boutons que voulu, et la décoration est jolie quelle que soit la taille du texte.

3. Appliquer cette méthode pour d'autres effets

Cette technique est efficace car elle s'applique à d'autres types de décorations ou d'effets. On peut rajouter des ombres à un élément. Ou mettre des bords compliqués: Il n'y a aucune limitation. Elle marche avec tous les navigateurs principaux (il faudra utiliser le hack ActiveX pour faire marcher les PNG sur IE 6). Il est possible de combiner toutes les images d'une décoration en un seul fichier pour réduire le nombre de requêtes HTTP, et ainsi éliminer le seul réal désavantage de cette méthode par rapport à la méthode de largeur fixe avec une seule image de fond.

Conclusion

Une fois mis en place les divs secondaires et les images, cette technique permet de décorer autant d'éléments que l'on veut sans se préoccuper de leurs dimensions. Vous pouvez vous concentrer sur le contenu de votre élément en étant sur que la décoration s'y ajustera. De manière étonnante, je n'ai pas trouver de tutoriel en ligne détaillant cette méthode. Kameleoon utilise une version plus globale (et plus complexe) de cette technique de base pour décorer les éléments de manière générique - le code HTML est ajouté à l'élément dynamiquement en JavaScript. Pour finir, cette méthode a des perspectives d'évolution naturelles : une fois CSS 3 implémenté par la plupart des navigateurs, passer à l'utilisation du module Fond (Background) sera aisé. Cela permettra de se débarasser du code HTML laid qui est malheureusement nécessaire en CSS2.