Envoyer un mail à l’auteur
xavier at ultra-fluide.com
par Douglas
Bowman en octobre 2003, traduit en français par Xavier Boully.
L'article
original publié en anglais sur A List Apart, a été traduit en français
avec l'autorisation de l'auteur Douglas Bowman et de Jeffrey Zeldman au nom
de A List Apart.
Les portes coulissantes en CSS (partie I) ont introduit une nouvelle technique autorisant la création d'interfaces sophistiquées sur le plan visuelle, et ce à partir d'un simple code HTML conservant les contenus textuels. Dans cette seconde partie nous allons pousser la technique encore un peu plus loin. La compréhension du présent article nécessite d'avoir parcouru la première partie.
Nous allons maintenant enrichir nos exigences : ouvrir à la possibilité qu'aucun onglets ne soit sélectionné, associer le principe des portes coulissantes avec le rollover à l'aide d'une image unique, corriger le problème relatif à la zone cliquable sous IE/Win et proposer une alternative pour la sélection des onglets. Vous trouverez les bases sur la partie I, et nous partirons directement des acquis de ce premier article.
Nous n'avions pas pris en compte la possibilité qu'aucun onglet ne soit
sélectionné. Par exemple un formulaire d'enregistrement ou un contenu
juridique peuvent ne pas correspondre à aucune des sections représentées par
les onglets. Si aucun des onglets ne porte l'attribut
id="current"
, la règle qui ajoute en bas un pixel supplémentaire
de padding ne sera jamais appliquée. Dans ce cas les onglets recouvrent la
bordure du bas du menu.
Ajouter une bordure de 1px en bas des onglets non sélectionnés, et retirer cette bordure sur l'onglet sélectionné résout la question :
#header li {
float:left;
background:url("left.gif")
no-repeat left top;
margin:0;
padding:0 0 0 9px;
border-bottom:1px solid #765;
}
#header #current {
background-image:url("left_on.gif");
border-width:0;
}
Voyons le résultat avec l'exemple 7.
Nous avions mis les rollovers de coté dans la partie I afin d'en préserver la simplicité. Maintenant que nous avons la technique de base sous contrôle, nous allons pouvoir y intégrer les rollovers pour perfectionner notre système de menu.
Il y a peu de temps encore, introduire un effet rollover - que ce soit en javascript ou en CSS - impliquait la création de deux ensembles d'images : un pour l'état normal, et l'autre pour le survol de la souris (hover). Afin d'éviter le temps de latence constaté au survol de la souris du au chargement indépendant des images, plusieurs méthodes existent pour pré charger les images requises dans le cache du navigateur. Petr Stanicek (aka “Pixy”) nous a montré dans "Fast Rollovers, No Preload Needed" (Rollovers rapides sans pré chargement) comment combiner les deux états (normal et hover) en une seule image, éliminant ainsi la nécessité de pré chargement.
Dans notre exemple, nous empilerons nos deux images de gauche l'une au dessus de l'autre pour rassembler les deux états sur une seule nouvelle image. Nous ferons de même pour les images de droit. Les images initiales de 150 pixels vont laisser place à des images de 300 pixels de hauteur. Voici donc left_both.gif et right_both.gif. Nous utiliserons la propriété background-position pour rendre visible la zone appropriée de l'image à deux états lorsque l'utilisateur effectue un survol de l'onglet avec sa souris :
Nous installons maintenant ces nouvelles images dans leurs éléments
respectifs li
et a
, à la même position :
#header li {
float:left;
background:url("left_both.gif")
no-repeat left top;
margin:0;
padding:0 0 0 9px;
border-bottom:1px solid #765;
}
#header a {
float:left;
display:block;
background:url("right_both.gif")
no-repeat right top;
padding:5px 15px 4px 6px;
text-decoration:none;
font-weight:bold;
color:#765;
}
L'utilisation de la propriété background-position nécessite de spécifier les deux coordonnées dans cet ordre : horizontal et vertical. Il n'est pas possible de préciser le positionnement à l'aide des sous propriétés habituelles (left, right, top, etc.). Nous préciserons pour notre image de gauche une position horizontale à 0% afin que son bord gauche soit contre le bord gauche de la fenêtre visible et 100% concernant l'image de droite pour un positionnement symétrique.
Nous connaissons exactement la structure de l'image, donc son
positionnement vertical peut se faire au pixel près. Les 150 pixels du haut
concernent l'état normal et les 150 autres l'état hover. Donc à gauche comme
à droite nous repoussons les images de 150 pixels vers le haut pour faire
apparaître l'état hover. Le sélecteur #header li:hover a
est
répété de façon à ne spécifier la couleur de fond qu'à un seul endroit.
#header li:hover, #header li:hover a {
background-position:0% -150px;
color:#333;
}
#header li:hover a {
background-position:100% -150px;
}
Nous utilisons les mêmes images pour l'onglet sélectionné. Ce dernier n'a qu'un état qui correspond à l'état hover de l'onglet normal :
#header #current {
background-position:0% -150px;
border-width:0;
}
#header #current a {
background-position:100% -150px;
padding-bottom:5px;
color:#333;
}
Et voilà notre effet rollover implémenté, c'est aussi simple que cela. Voyons le en action dans l'exemple 8. Nous avons réduit le nombre total d'images utilisées de cinq (2 à gauche, 2 à droite, 1pour le fond) à 3 (1 à gauche, 1 à droite, 1pour le fond), et évité de recourir à un préchargement.
Si vous avez testé notre travail sous Internet Explorer (Mac ou PC), vous avez pu remarquer que le rollover ne fonctionne pas. En effet, IE n'applique la pseudo classe :hover qu'aux liens. Le mettre à la portée d'IE impliquerait un élément supplémentaire (tel qu'un élément span) à insérer dans le lien, et le décalage d'un cran de toutes nos règles (élément li vers élément a, et élément a vers élément span).
Nous n'irons pas dans le détail des ajustements nécessaires pour obtenir le rollover sous IE. Vérifiez simplement ces adaptations avec l'exemple 8a. Comme vous pouvez le constater, décaler le rôle de chaque élément élimine également la zone non cliquable mentionnée dans la partie I puisque maintenant le lien contient l'ensemble de l'onglet.
Les Rollovers sont souvent des effets d'ordre décoratif. Certains d'entre vous pourrons considérer que le code supplémentaire nécessaire pour IE n'en vaut pas le coût. D'autres penserons qu'il s'agit là d'un petit sacrifice pour avoir un effet rollover sur un navigateur populaire et éliminer en même temps la zone non cliquable. Introduire ce code supplémentaire relève de votre propre choix.
Comme dans le cas des onglets de la partie I, les liens peuvent être changés en éléments block, et un padding supplémentaire peut être introduit pour étendre la région cliquable. La zone visible est le plus souvent remplie d'une couleur d'arrière plan (ou d'une image d'arrière plan dans notre exemple) ce qui laisse penser à l'internaute qu'il est possible de cliquer n'importe où dans cette zone, pas seulement sur le contenu des liens. Dans la plupart des navigateurs, lorsqu'un lien est changé en élément block (via CSS) et qu'un padding est ajouté à ce lien, sa partie visible et sa partie cliquable s'étendent concomitamment pour couvrir le contenu et le padding. Malheureusement IE/Win n'étend que la région visible et confine la région cliquable au seul contenu :
Dans la partie I (et avec l'exemple 8a au dessus), nous avons noté un petit espace mort sur la gauche de l'onglet du fait de la partie transparente de l'image. Nous avions noté les conditions nécessaires pour éviter cette zone insensible à la souris. Cependant la partie I n'avait pas couvert la limitation relative à l'étroitesse de la zone cliquable sous IE/Win. Ce navigateur (version 6.0 et inférieures) souffre de plusieurs bogues dans l'implémentation de CSS. Certains bogues produisent des problèmes inattendus - et parfois même non répertoriés - pour l'utilisation et l'accessibilité de systèmes de navigation basés sur CSS.
Spécifier la largeur ou la hauteur d'un lien va forcer IE comme par magie à étendre sa région cliquable. Mais cela s'opposerait à la flexibilité que nous attendons de la taille des onglets. Vous pensez peut-être que nous pourrions spécifier une hauteur ou une largeur en "em". Cela réglerait la taille des onglets sur la taille de la police du texte contenu par héritage. Mais utiliser une hauteur sur un lien rend IE/Win complètement fou. Concernant la largeur, à moins d'utiliser une police à espacement fixe, la déterminer en em va rendre la largeur de l'onglet inappropriée par rapport au texte dont la largeur aura été réévaluée. (Sans compter la lourdeur due à la nécessité de déterminer une largeur pour chaque onglet en fonction du texte qu'il contient).
Heureusement pour nous, nous allons pouvoir exploiter un autre défaut de IE/Win dans son implémentation de CSS, le forçant à étendre la zone cliquable sans pour autant déterminer une largeur arbitraire. Tout ce que nous devons faire est de spécifier une très petite largeur sur le lien. La plupart des navigateurs sont stricts dans l'application de la largeur d'un élément block, indépendamment de la largeur du contenu : l'élément va se réduire à la largeur spécifiée même si son contenu doit dépasser ses frontières. Au contraire IE/Win réduit l'élément à la largeur de la plus longue ligne de texte insécable.
Donc même si nous spécifions une largeur vraiment étroite (.1em par exemple), IE/Win va tout de même rendre le lien aussi large que son contenu. Dans le même temps IE va étendre la région cliquable jusqu'à remplir tout l'onglet :
#header a {
float:left;
display:block;
width:.1em;
background:url("right.gif")
no-repeat right top;
padding:5px 15px 4px 6px;
text-decoration:none;
font-weight:bold;
color:#765;
}
Ceci parait n'avoir aucune logique, dans la mesure ou les deux idées vont en sens opposées. Cependant le problème de la zone cliquable réduite sous IE./Win est maintenant résolue. Maintenant nous devons garder à l'esprit que les autres navigateurs vont coller à la spécification et réduire la largeur de l'onglet à .1em + padding. Heureusement, IE/Win (6.0 et inférieure) ne comprend pas le sélecteur d'enfant , caractéristique qui nous facilite la tâche pour remettre la largeur à la valeur auto en direction des autres navigateurs, et laisser ainsi la taille des onglets libre :
#header > ul a {width:auto;}
L'exemple 9 présente cette solution.
Jusqu'à présent, un seul des onglets était ciblé à l'aide de l'attribut id pour en faire l'onglet sélectionné. Changer la position de l'attribut id d'un onglet à l'autre est simple à comprendre pour qui débute sur CSS. Cependant, il existe un autre moyen de cibler l'onglet sélectionné, peut-être plus efficace dans bien des cas, même si en contrepartie cette méthode nécessite l'ajout d'un peu de code.
Au lieu d'utiliser id="current"
pour identifier l'onglet
sélectionné, nous pourrions appliquer un identifiant unique pour chaque
onglet :
<div id="header">
<ul>
<li id="nav-home"><a href="#">Home</a></li>
<li id="nav-news"><a href="#">News</a></li>
<li id="nav-products"><a href="#">Produits</a></li>
<li id="nav-about"><a href="#">A propos</a></li>
</ul>
</div>
Nous appliquons également un identifiant à un container plus large,
l'élément body par exemple. Cet identifiant correspond à une rubrique dans
laquelle cette page s'insère. L'identifiant positionné sur l'élément body
peut également servir pour appliquer un style spécifique à la rubrique dans
d'autres parties de la page. Cces identifiants localisés aux deux endroits,
permettent de modifier l'apparence de certains onglets lorsque les conditions
des sélecteurs
descendants sont remplies. Plutôt que d'introduire #current
dans le sélecteur, nous utiliserons la combinaison des identifiants de
l'élément body et des items de la liste pour définir l'onglet sélectionné
:
#home #nav-home, #news #nav-news,
#products #nav-products,
#about #nav-about {
background-position:0% -150px;
border-width:0;
}
#home #nav-home a,
#news #nav-news a,
#products #nav-products a,
#about #nav-about a {
background-position:100% -150px;
color:#333;
padding-bottom:5px;
}
L'exemple
10 montre le résultant lorsque l'on applique id="news"
à
l'élément body, et l'exemple 10a
applique id="products"
.
Structure d'entête : Il se peut que vous ayez sur vos pages des blocks qui structurent le haut de page et rehaussent d'un rectangle par exemple l'entête et son contenu. En supposant que vous utilisez un container (une div par exemple) pour emballer cette construction, vous disposez donc de deux éléments (la div et l'entête) pour l'image de fond. Dans ce cas, vous préférerez placer l'image étroite de l'onglet à droite comme dans l'exemple 2. Cela donne effectivement un contrôle complet sur la position du texte à gauche. On peut également s'arranger pour fondre le bas de chaque image dans la couleur du fond de l'enveloppe pour donner l'impression que tout est d'un seul tenant.
Rotation de 90° : Si vous pouvez prévoir approximativement la hauteur d'un élément d'interface (ou si vous avez des images qui laissent suffisamment de marge pour absorber des variations en hauteur), vous pouvez tournez la "porte" de 90°, et utiliser une image pour le haut et une image pour le bas (au lieu d'une répartition droite gauche). Il faut cependant prévoir une largeur suffisante qui puisse accepter les variations de taille du texte que l'utilisateur peut imposer dans son navigateur.
Scintillement sous IE : Si vous voyez les images
scintiller (voire clignoter) au survol de la souris dans IE/Win, vérifiez les
préférences concernant la gestion du cache (Outils > Options Internet >
Onglet général > Paramètres). Vous avez peut-être changé les valeurs par
défaut afin de recevoir systématiquement la dernière version de la page
visitée. IE/Win a un problème pour maintenir la stabilité des images en
arrière plan des liens avec le paramétrage "A chaque visite de la page". Le
paramètre par défaut est "Automatiquement", il permet au navigateur de
chercher l'image dans le cache, évitant ainsi tout scintillement. La plupart
des utilisateurs ne change jamais cette préférence, et souvent ils ignorent
même son existence.
Note du traducteur : il existe d'autres
solutions pour éviter
le scintillement sous IE
Onglets de plusieurs mots : Si vous avez besoin, comme on
le voit souvent, de définir le texte des onglets avec plusieurs mots, vous
devriez ajouter white-space:nowrap;
à la règle définissant le
comportement des liens. Cela évitera un retour à la ligne entre deux mots
dans un onglet.
Il y a certainement d'autres choses à dire sur cette technique pour corriger des défauts, l'améliorer ou la perfectionner. Nous nous arrêterons ici cependant, espérant avoir déjà répondu à nombre de questions relativement à cette technique souple et bien pratique des portes coulissantes.
Agence de communication Ultra-Fluide : 01 47 70 23 32 - contact at ultra-fluide.com - 44 rue Richer 75009 Paris.